Glance/24 — 크고 느낌있는 아날로그 스타일

스마트시계라고 하지만 나는 아날로그 스타일을 선호한다.  숫자 가득한 화면이나 갖가지 알림으로 가득한 디지털화면은 질색이다.  손으로 쓰거나 그린 밑바탕을 깔고 유치하다싶을 애니메이션을 곁들이면 더 좋겠다.  혹은 뭔가 잊어버리지 말아야할 내용을 멋들어진 곡선이나 기호로 표시해도 좋겠고 약속이나 명심하고 다녀야할 내용을 표시해주는 것도 나쁘지 않다.

 

보고서가 잘 써지지 않던차에 그냥 슬쩍~ 만들어본 페블 시계화면이다.

 

Resizing ..

시계크기 조절

adjust padding..

패딩 조절

adjust hand width ..

시침 크기 조절

glance-anim

잠에서 깨어난뒤 감기

SlowSUNNY v2 화면에 기본을 두고 확대해서 보고싶었다.  확대해보니 나름 괜찮길래 스마트폰에서 설정창 열어 조절하지 않고 그냥 시계에서 여러 옵션을 처리했다.  지난 5월부터 사용중인 Pebble Steel는 7개월 정도 지난 시점에서 하루에 한칸~두칸 정도 배터리 소모를 보이고있다.  실망스런 배터리 덕분에 3~4일에 한번 충전하고 있다. 1년 정도 지나면 1~2일 정도로 떨어질지도 모른다 -__-);;  완전 밀폐되어있으니 배터리 교환하려면 망칠 각오하고 페블 뚜껑을 열어야할 것 이다.

 

 

Glance/24 v2.0 (비공개버전)

 

* 확대된 스타일의 Watch Application 타입이다.

* 모든 설정을 스마트폰을 거치지 않고 시계에서 바로 조절가능한다.

* 12/24시간 두개의 스타일을 지원한다.

 

* 배터리 소모를 줄이기 위해 세가지 모드를 지원한다:

- 일반 모드 (매 분마다 시간을 업데이트 한다)

- 잠자기 모드 (업데이트 하지 않는다. 깨어난 후, 잠든시간부터 현재시간까지 시침을 감는다)

- 흔들어 깨우기 모드 (흔들거나 Down 버튼을 누르면  시간을 업데이트 한다)

 

* 배터리, 블루투스 연결을 모니터링해서 끊어지거나 연결되면 알려준다.

* 시계크기, 시침 크기, 시침 모양, 패팅 등의 사이즈 조절이 가능하다.

* 프로그램 시작시 마지막 종료시점부터 시간차가 하루인 경우에 시침을 감는다.

 

* 버튼 사용법 ( 클릭하면 확대~)

 

 

glance24-v2.0-guide

 

 

 


무료버전 v1.0 (2014-11-28)

24시간 스타일만 지원하는 Watchface 스타일 어플이고 현재 페블 앱스토어에서 다운받을 수 있다: 

https://apps.getpebble.com/applications/547851566e0cd30c8e000038

pebble://appstore/54249c5c5f5a58462f0000fd

 

* 지금은 무료지만 Heart, 다운로드 수가 생각보다 적으면 내려버릴 예정이다.

vim auto-completion for Pebble programming

auto-completion-using-vim-for-pebble

It is noticed that CloudPebble now supports code completion, syntax checking and ability to "go to definition" 1. But you can also get all these benefits by using vim and ctags in console. I will describe brief explanation for those who are already using vim as their primary developing tool for developing pebble application.

 

You need ctags and remap C language files

Install ctags first, and check out the mapping list for C definition.

1
2
3
$ ctags --list-maps=C

C        *.c *.h

 

If you find different output for *.h files, you need to remap as follow. To avoid specify same option on every command to build tags file, add the below line to your ~/.ctags file.  Make new one if it doesn't exist.

1
--langmap=C:.c.h

 

Install YouCompleteMe plugin for vim and follow its instruction to gear up.

Most case, you need nothing  to do but just install plugin and compile the C-components.

Github: https://github.com/Valloric/YouCompleteMe 2

 

Add or apply the below to your existing .vimrc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
"search tags file recursively from working directory until reach '/' directory.
set tags=./tags;

"automatic update/create tags file

au BufWritePost *.c,*.h silent! !ctags --fields=+l --C-kinds=+p -R % &

"Plugin: YouCompleteMe {{{


let g:ycm_global_ycm_extra_conf = "~/.vim/ycm_extra_conf.py"
let g:ycm_confirm_extra_conf = 0
let g:ycm_min_num_of_chars_for_completion = 2
let g:ycm_auto_trigger = 1
let g:ycm_collect_identifiers_from_tags_files = 1
let g:ycm_seed_identifiers_with_syntax = 1
let g:ycm_add_preview_to_completeopt = 1
let g:ycm_autoclose_preview_window_after_completion = 1
let g:ycm_key_invoke_completion = ''

"define as you want

nnoremap jd :YcmCompleter GoTo;

" }}}

 

Add or apply the below to your existing ycm_extra_conf.py. If it is not exist, copy from ~/.vim/bundle/YouCompleteMe/third_party/ycmd/examples/.ycm_extra_conf.py into ~/.vim/ycm_extra_conf.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import os
import ycm_core

flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-std=c11',
'-x', 'c',
'-I.',
'-I', '/Users/andrwj/pebble-dev/PebbleSDK-current/arm-cs-tools/arm-none-eabi/include',
'-I', '/Users/andrwj/pebble-dev/PebbleSDK-current/Pebble/include'
]
#...
#...

 

Build tags file for Pebble SDK

I assume that users already installed Pebble SDK at ~/pebble-dev/PebbleSDK-current

 

1
2
3
4
5
6
7
8
9
10
11
$ cd ~/pebble-dev/PebbleSDK-current
$  rm -f tags
$ ctags -R \
--fields=+l \
--C-kinds=+p \
--exclude=~/pebble-dev/PebbleSDK-current/arm-cs-tools/arm-none-eabi/include/c++ \
~/pebble-dev/PebbleSDK-current/arm-cs-tools/arm-none-eabi/include \
~/pebble-dev/PebbleSDK-current/Pebble/include

$ ls -lah tags
-rw-r--r--  1 andrwj  staff   2.3M 10 15 14:39 tags

 

 Install syntax plugin for Pebble

We need this plugin because to seed identifiers of Pebble API from syntax file.

Github: https://github.com/ZDBioHazard/pebble-vim-syntax 3

 

As described in author's README.md, don't forget to add the below line:

1
autocmd BufNewFile,BufRead ~/pebble-dev/*.{c,h} set syntax=pebble

 

OK,  one last.

In order to use auto-completion for Pebble API, you need to place pebble-project files somewhere of ~/pebble-dev/ Because YouCompleteMe plugin seeks tags file recursively from current working directory until reach /.   The plugin refers ~/pebble-dev/PebbleSDK-current/tags file for auto-completion.

 

As you type, identifiers will be shown up. then you press <CTRL-Space> to auto-complete. You can also jump to the definition of constants, functions, macros by pressing <leader>jd or CTRL-].

 

Good luck!

 

  1. https://developer.getpebble.com/blog/2014/10/09/CloudPebble-code-completion/  
  2. https://github.com/Valloric/YouCompleteMe  
  3. https://github.com/ZDBioHazard/pebble-vim-syntax  

JavaScript로 설명한 C의 더블 포인터

이전 게시물에서 얘기한 내용의 예시로써,  C언어의 더블 포인터를 어떻게 써야할지 이해하지 못한 학습자를 위해 JavaScript코드로 설명하였다.   이글은 JavaScript에 대해 초급지식을 가지고 있는 C학습자를 대상으로 한다.

 

 


 

변수에 값을 넣는 것을 할당(assign)이라 하고 JavaScript 변수에 할당하는 값의 종류에는 크기가 고정된 Primitive type과  고정되지 않은 Reference type 두가지 종류가 있다. 1 Number, Boolean, undefined, null 은 Primitive Type이고 그외 배열, 객체, 함수 등은 Reference Type이다.

 

Reference Type 값은 모두 실행시간에 그 크기가 동적으로 변한다. C언어적으로 말하자면 malloc() 받는다고 할 수 있으며 Reference Type의 값을 담고 있는 변수는 그 값자체가 아니라  그 값의 메모리 주소를 담고 있다. 즉, C언어의 포인터 변수인 것이다.

 

Reference Type의 값을 가진 변수에 대해, 넣어진 값을 꺼내보거나 사용하는 것을 참조한다(refer) 라고 표현하자.  아래 JavaScript 코드에서는 변수 target에  Reference Type의 값 [1,2,3]이 할당되고  변수 A, B에는  변수 target의 복사된 값이 할당된다:

1
2
3
4
5
6
7
function doSomething(A, B) {
console.log(A);
console.log(B);
}

var target = [1,2,3];
doSomething(target, target);

 

target, A, B 세 변수는 이름만 다를뿐 모두 같은 값인 [1,2,3]의 주소를 가지고 있다(pointing).  몇몇 학습자는  A, B 두 변수는 target을 가리키는 변수 라고 생각할 수 도 있겠으나 틀린 생각이다. 변수를 가리키는 변수는 JavaScript 에서 지원하지 않기 때문이다.  만약 지원한다면 target은 Reference Type의 값을 가지고 있으니 C언어로 표현될 때 포인터 변수이며 A,B는 포인터 변수를 가리키고 있으므로 더블 포인터 변수가 될것이다. 

 

배열은 Reference Type Value이므로, 함수의 인자로 전달되어 그 함수에서 배열에 가해진 변경사항은 target 변수에서도 동일하게 보여진다:

1
2
3
4
5
6
function doSomething(A) {
A[2]  = 5;
}

var target = [1,2,3];
doSomething(target); //세번째 요소의 값이 3에서 5로 변한다.

 

이런 뻔한 소리를 하는 이유는, 거의 모든 JavaScript 개발자들이 C언어에서 말하는 포인터변수와 동일한 Reference Type Value를 가진 변수조작을 아무런 어려움없이 해내고 있다는 것을 말하고 싶어서이다.

 

JavaScript에서는 포인터 변수에 해당하는 것을 쓰더라도 C언어 포인터변수의 선언과 값 할당에 사용하는 * (Asterisk sign)  기호를 사용하지 않기 때문에  그럴수도 있고 포인터 값을 사용할때 (referencing) ->표기를 하지 않아 덜 복잡해 보이기 때문일수도 있다.  원인이 무엇이든 상관없이 모든 초급 C학습자는 포인터 개념을 모르는게 아니며 분명히 어떻게 사용해야할지 스스로 알고있다.  Reference Type으로 값을 함수에 전달하는 것이 프로그램 실행속도에 더 나은 선택이며 효율적인 코드를 작성할 수 있다는 것은 말하지 않아도 안다.

 

그런데,, 더블 포인터라는 말이 나오면 일단 머리가 띵~해지려고 한다. 도대체 왜 그딴 것을 쓰는지 언제 써야하는지 도대체 모르겠다는 것이다.  더블 포인터가 얼마나 간단한 개념인지 체감하기 위해, 여기서 문제를 내겠다. 반드시 고민해서 답을 달려고 해보자. 고민하지 않고 그냥 글을 읽어내려가면 A-HAAA~! 라는 깨달음이 덜 느껴질지도 ..

 

 

문제:

위의 예제에서 보이는 doSomething() 함수내에서 target 변수의 값이 undefined 가 되도록 해보라. 단 doSomething() 함수내에서 target이라는 변수 이름을 직접적으로 사용할 수는 없다.

 


 

...

 

 

...............

 

 

 

...

 

 

 

 

.......

 

 

 

 

....................

 

 

 

 

 

...........

 

 

 

 

 

 

................

 

 

 

 

 

 

.......

 

 

고민해보았는가?

 

 

........

 

 

...

 

 

.............

 

 

 

 

 

..

 

 

 

 

 

 

 

 

변수 target을 직접적으로 사용할 수 없으므로 여러분은 그 변수의 값을 빈 배열로 만들 수는 있어도 undefined가 되게 하는 것은 힘들다는 것을 알았을 것이다.

예시코드: http://jsbin.com/fasebijepuri/1/edit#javascript,console

1
2
3
4
5
6
7
function doSomething(A) {
while(A.pop());
}

var target=[1,2,3];
doSomething(target);
console.log(target); // 'undefined'가 아닌  '[ ]'

 

이 문제를 해결하기 위해서 프로그래밍 언어가 무엇을 지원해야하는지 생각해보자...

 

만약, 해당 변수와 다른 이름이지만 그 변수와 동일하게 취급받는 변수를 만들 수 있다면 가능하지 않겠는가?   즉, 변수를 가리키는 변수 같은 종류라면 가능할 것이다.  더 쉬운 말로 변수의 별명(Alias) 이라 표현할 수 있다.  

 

JavaScript에서 위의 문제를 해결하기 힘든 것은 Reference Type Value를 담는 변수는 C언어로 표현할 때 single pointer 변수 이기 때문이다. 즉, 값을 가리킬뿐 변수를 가리키지는 않는다.   이 점을 기억하고 C언어적인 해결방법을 얘기하자.  단도직입적으로 이 문제의 해법으로 더블 포인터 변수를 사용할 수 있다.

 

다음과 같이 main() 함수내에서 메모리를 할당하고 doSomething()함수내에서 그 변수에 할당된 메모리를 해제하는 코드를 보자. 코드의 복잡성에 신경쓰지 말고 main() 함수내의 변수를 main()함수 밖에서 어떻게 조작하는지에 대한 것만 신경쓰자:

1
2
3
4
5
6
7
8
9
10
11
void doSomething(void **A) {       // double pointer
free(*A);       // A==&amp;target 이고 *A==target 이다
*A=0;
}

int main(void) {
void *target = malloc( 8 );          //(의미없는) 8바이트 메모리를 동적으로 할당하여 포인터 변수에 넣는다.
doSomething(&amp;target);   //포인터의 주소를 인자로 넘긴다.
if(target==0) printf("empty\n");     //main()함수 밖에서 직접 target 변수를 조작하였다. 따라서 출력은 <code>0</code>
return 0;
}

 

A==&target 이고 *A==target 이므로 *A 코드로써 target 변수 이름을 직접 쓰지 않고 main() 함수 밖에서 main()함수내의 변수에 할당된 메모리를 해제하고 0을 직접 넣었다!

 

이처럼 변수에  askterisk(*) 가 두개나 붙어서 복잡해 보여도 더블 포인터는 단순히 별명이라고 생각하면 어떻게 활용해야하며 무엇을 해야할지 굳이 일일이 나열하지 않아도 어느정도는 감을 잡을 수 있다.  더블포인터 떡칠했다고 머리 아퍼할 이유도 없다.

 

연습을 통해 자신있게 사용할 수 있게되는 것은 시간문제일 것이다. Good Luck!

  1. http://docstore.mik.ua/orelly/webprog/jscript/ch04_04.htm