пятница, 9 декабря 2016 г.

Не работает Playground? Восстанавливаем

Часто с моим Xcode бывает следующая ситуация: Playground вроде бы и работает, но не показывает результаты. В этом случае мне помогает вот такая последовательность действий:

  • Выходим из Xcode.app и Simulator.app;
  • В терминале: 
    $ rm -fr ~/Library/Developer/*
    $ sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService
    $ rm -rf ~/Library/*/CoreSimulator
  • ЗапускаемXcode (и Simulator.app);
Ну, что еще добавить? Будьте осторожны с командой rm. 

пятница, 25 ноября 2016 г.

Язык Swift: массивы и словари


Рассмотрим коротко массив:
  • Массив - это упорядоченный список значений (величин, элементов);
  • Каждая величина в массиве позиционируется целым числом или индексом. Первая величина в списке имеет индекс 0;
Проиллюстрируем это куском из Playground:
var str = "Hello, playground"
var myArray1: Array<String> = ["myString1","myString2"]
var myArray2: [String] = ["myString3", "myString4"]
let myArray3: [String] = ["myString5", "myString6"]
let myArray4 = ["myString7","myString8"]
var myArray5 = [String]()
var myArray6 = Array<String>()
var myArray7: Array<AnyObject>
Перечислим типичные действия, что мы можем применить к массивам:
  • С помощью свойства count определяется число элементов в массиве;
  • Получение значения элемента массива с помощью индекса;
  • Добавление нового элемента к массиву с помощью функции append(_) или оператора +=;
  • Удаление выбранного элемента с помощью функции remove(at:);
  • Добавление нового элемента в массив в указанную позицию помощью функции insert(_,at:);
  • Изменение значения выбранного элемента с помощью оператора =;
  • Просмотр содержимого массива с помощью цикла for-in;
Проиллюстрируем это куском из Playground:
print("number elements in the array: \(myArray1.count)")
print("\(myArray1[1])")
myArray1.append("myString9")
myArray1+=["myString10"]
myArray1.remove(at: 0)
myArray1.insert("myString11", at: 1)
myArray1[0]="myString12"
for i in myArray1{
    print("\(i)")
}
Аналогично рассмотрим словарь:
  • Словарь - это неупорядоченный список абстрактных пар ключ-значение (ключ-величина, ключ-элемент);
  • Как в массиве элемент определяется по индексом, величиной целого типа, так и в словаре элемент определяется ключом, величиной любого типа. Я думаю, что можно говорить об массиве как частном случае словаря;
  • На практике в большинстве случаев тип ключа - это String;

Проиллюстрируем это куском из Playground:
var myDictionary1: Dictionary<String, String> = [:]
var myDictionary2: Dictionary<String, String> = ["myKey1":"myValue1","myKey2":"myValue2"]
var myDictionary3: [String: String] = ["myKey3":"myValue3","myKey4":"myValue4"]
var myDictionary4 = [String:String]()
var myDictionary5 = Dictionary<String, String>()

Перечислим типичные действия, что мы можем применить к словарям:
  • С помощью свойства count определяется число пар в словаре;
  • Получение значения элемента с помощью ключа;
  • Изменение значения элемента с данным ключом с помощью функции updateValue(_,forKey:) или оператора =;
  • Добавление новой пары ключ-значение;
  • Удаление пары пары ключ-значение с помощью функции removeValue(forKey:) либо присваиванием удаляемому элементу значения nil;
  • Просмотр содержимого словаря с помощью цикла for-in;
Проиллюстрируем это куском из Playground:
print("number elements in the dictionary:\(myDictionary2.count)")
print("\(myDictionary2["myKey2"]!)")
myDictionary2.updateValue("newMyValue2", forKey: "myKey2")
print("\(myDictionary2["myKey2"]!)")
myDictionary2["myKey2"] = "new2MyValue2"
print("\(myDictionary2["myKey2"]!)")
myDictionary2["myKey5"] = "myValue5"
myDictionary2.removeValue(forKey: "myKey1")
let arrayOfMyKeys = [String] (myDictionary2.keys)
let arrayOfMyValues = [String] (myDictionary2.values)
for i in arrayOfMyKeys{
    print("\(myDictionary2[i]!)")
}


четверг, 13 октября 2016 г.

Минимальный набор команд OpenGL для работы с вершинным шейдером

Каждая более менее простая программа OpenGL традиционно состоит из трех стандартных частей: инициализирующая, отвечающая на сообщения об изменении размеров сцены, собственно рисующая,  деинициализирующая. Поэтому далее приведенные инструкции расположены в порядке их использования и разделены на эти соответствующие части.
Список переменных, которые понадобятся:

Glint programID = 0;
GLuint vaoID = 0;
char[] source = "the code1";//коды шейдеров
char[] source = "the code2";
Glint logLength = 0;
GLint compiled = 0;
GLint linked = 0;

Список команд в инициализирующей части:

programID = glCreateProgram();
glGenVertexArrays(1, &vaoID);
vs = glCreateShader(GLenum(GL_VERTEX_SHADER));
glShaderSource(vs, 1, &source, nil);
glCompileShader(vs);

//Работа с логами и кодами возврата компиляции шейдера
glGetShaderiv(vs, GLbitfield(GL_COMPILE_STATUS), &compiled);
glGetShaderiv(vs, GLenum(GL_INFO_LOG_LENGTH), &logLength);
glGetShaderInfoLog(vs, GLsizei(logLength), &logLength, cLog);
free(cLog);

fs = glCreateShader(GLenum(GL_FRAGMENT_SHADER));
glShaderSource(fs, 1, &fssptr, nil);
glCompileShader(fs);
//Здесь надо повторить обработку кода возврата компиляции и лог

glAttachShader(programID, vs);
glAttachShader(programID, fs);
glLinkProgram(programID);

//Работа с логами и кодами возврата линковки шейдера
glGetProgramiv(programID, UInt32(GL_LINK_STATUS), &linked);
glGetProgramiv(programID, UInt32(GL_INFO_LOG_LENGTH), &logLength);
glGetProgramInfoLog(programID, GLsizei(logLength), &logLength, cLog);

glDeleteShader(vs);
glDeleteShader(fs);

Список команд в рисующей части:
glClear(GLbitfield(GL_COLOR_BUFFER_BIT));
glUseProgram(programID);
glBindVertexArray(vaoID);

//glPointSize(40); и т.п.

glDrawArrays(GLenum(GL_POINTS), 0, 1);
        
glBindVertexArray(0);       
glFlush();

По завершении работы необходимо освободить ресурсы:

glDeleteVertexArrays(1, &vaoID);
glDeleteProgram(programID);

Это некая абстрактная схема, выраженная в виде инструкций на языке Си. На "человеческом" языке этот алгоритм можно описать так:

  1. Создаем пустую программу с идентификатором programID;
  2. Создаем массив вершин;
  3. Задаем исходники шейдера вершин;
  4. Компилируем их;
  5. Смотрим, есть ли ошибки компиляции, и обрабатываем их;
  6. Повторяем шаги 2-5 для других массивов;
  7. Привязываем все скомпиллированные шейдеры к программе programID;
  8. Компонуем ее;
  9. Смотрим, есть ли ошибки компоновки, и обрабатываем их;
  10. Вытираем шейдеры; Все готово для команд рисования;
  11. Указываем, что будем пользоваться программой с индентификатором programID; Я так понял, что таких "программ" может быть несколько в одном приложении и мы можем переключаться между ними;
  12. "Привязываем" массив вершин;
  13. glDrawArrays - рисуем;
  14. "Отвязываем" массив вершин;
  15. При выходе из приложения явно вытираем массивы вершин и "программы";

среда, 5 октября 2016 г.

Чистый десктоп в Mac OS X

Часто советуют для ускорения работы мака очистить десктоп от всех файлов на нем или сделать их невидимыми (Зачем нужен тогда этот десктоп вообще?). С терминала добиться этой невидимости можно такой командой:
#defaults write com.apple.finder CreateDesktop -bool false
#killall Finder
Вернуть все назад можно так:
#defaults write com.apple.finder CreateDesktop -bool true
#killall Finder