Embedded ruby tutorial

루비 | 2012/04/20 10:43 | Posted by DMW
크리에이티브 커먼즈 라이선스
Creative Commons License

여기선 뭘 할거냐면.... http://www.filepang.co.kr/entry/Cpp-Simple-MVC-example 여기에 있는 간단한 C++ MCV 예제 중 뷰 부분을 루비로 빼내고 C++ 어플에 루비 인터프리터를 내장시켜서 동작을 시켜볼꺼다. 아래 클래스 다이어그림에서 루비라고 표시되어 있는 부분은 루비 인터프리터가 돌리고 나머지 부분은 C++ native로 동작하게 된다. 물론 결과물은 똑같이 시계다. 자세한 내용을 설명하진 않을꺼고 이러이러한 방법으로 배워나가면 된다고 적을꺼다. 그러니까 공략...일종의 walkthrough다. 내가 미리 삽질을 해 놨으니 쭉 따라오구 새로운 내용을 알아내면 같이 공유하면 된다능.


아직 그림이 업ㅂ다.


원래 시작은 루비 소스코드의 README.EXT(http://svn.ruby-lang.org/repos/ruby/trunk/README.EXT)를 읽는것으로 해야 된다고 카더라능. 하지만 맨땅에 해딩하면 너무 고달프니까 Pickaxe 3rd edition의 extend ruby 챕터를 보면 된다. 그래서 책을 사야 되냐? 않사도 된다. Pragmatic Bookshelf에서 해당 챕터는 공짜로 볼 수 있다. 아래 링크를 눌러서 기본적인 내용을 곡괭이 책에서 보자.


http://media.pragprog.com/titles/ruby3/ext_ruby.pdf


위 문서를 읽어보면 알겠지만 libruby에서 오픈해주는 API를 가지고 C extension을 만들어 보고 인터프리터도 내장시켜보고 막막 이것저것 해본다. 이것도 맨땅에 해딩이나 다름업ㅂ지만 저걸 안해보면 다음 단계로 나가는데 어려움이 있다. 뭘 어떻게 하던 삽질은 한번 해봐야된다능. 내용을 잘 읽어보고 예제를 잘 실행시켜보자. (참고로 루비 버젼마다 조금씩 다르다. 한쿡어로 번역된 1.8 기준용 곡괭이를 보고 요즘 많이 쓰는 루비 1.9에서 해보다보면 에로 사항이 꽃을 피울꺼라능)


저걸 다 읽어봤으면 이제 두가지 선택을 할 수 있다. 하나는 SWIG의 도움을 받는것이고 다른 하나는 Rice의 도움을 받는것이다. SWIG가 뭔지 모른다면 아래 링크를 눌러보자능.


http://www.filepang.co.kr/entry/SWIG-Ruby


따라해보면 간단한 C extension을 쉽게 만들 수 있다. 물론 상대적으로 쉽다. 나는 Rice 선택지를 골라서 공략했기 때문에 SWIG에 대한 더 자세한 내용은 적을 수가 업ㅂ다. 그래도 뭘 더 공부해야 되는지는 안다. SWIG Documentation에서 SWIG 자체를 공부하고 루비에 특화된 내용을 더 공부하면 된다. 아래 링크를 열심히 보면 된다. 엄청 길다 -_-;;;

http://www.swig.org/Doc2.0/SWIGDocumentation.html

SWIG 선택지에 거부감을 느꼈으면 계속 이 문서를 따라오면 된다. 일단 Rice가 뭐냐면 루비 C API(libruby)를 C++로 레핑 해놓은 라이브러리다. 당연히 C++의 강력한 기능, 탬플릿 메타 프로그래밍을 쓰고 있고 생각보다 사용하기도 참 쉽다. 일단 설치를 해야 되는데 gem으로 깔 수 있다.


$ gem install rice


그리고 github에서 Rice의 소스코드를 내려 받는다. 빌드하려고 받는건 아니고 같이 들어있는 테스트 코드가 정말 큰 도움이 된다. 문서 보다 더 쓸만하니 꼭 내려받자.


https://github.com/jameskilton/rice/tree/master/test


준비가 끝났으면 몇가지 코드를 읽어보고 빌드해보고 실행해보면 된다능!


아직 쓰고 있다!





저작자 표시 비영리 동일 조건 변경 허락

'루비' 카테고리의 다른 글

Embedded ruby tutorial  (2) 2012/04/20
Ruby + Chipmunk + Gosu  (2) 2010/09/27
ruby-opengl 0.32g for ruby1.9  (0) 2010/09/18
SWIG Ruby  (0) 2010/03/29
중위표현식을 후위포현식으로 바꾸기  (0) 2009/11/28
Queue  (6) 2009/09/22

댓글을 달아 주세요

  1. LaLuna 2012/04/27 13:31  댓글주소  수정/삭제  댓글쓰기

    이게 다 무어냐능

크리에이티브 커먼즈 라이선스
Creative Commons License

난 이런게 있는줄 몰랐는데 몇일전에 서버를 새로 사러 홈플러스에 갔는데 팔고 있길래 사왔다능. 만5천원이던데 두개에 7천원짜리 커피잔이랑 같이 사왔음.

 

뜯어서 분리시켜보면 이렇게 생겼음. 

중간에 보이는 용기에 물을 넣고 오른쪽에 있는 바구니에 커피를 담고 합체 시켜서 가스렌지로 끓이면 증기압이 생겨서 대롱을 타고 물이 올라가면서 커피가 추출되는 그런 방식이라능. 자세한 사용법은 박스 옆면에 친절하게 써있는데...이것만 가지고는 좀 부족하니 '모카포트'로 검색해보면 주의할 점이 막 나온다능. 유툽에서 'moka pot'으로 검색하면 동영상도 많이 나오니 몇개를 미리 보고 사용하자.

가스레인지에 올려놓고 끓이기 쉽게 사발이가 함께 들어 있는데 이런 모습으로 올려놓고 사용하면 된다. 

중간불로 적당히 끓이다 부글부글 소리가 나면 약한불로 줄이면 잠시뒤에 커피가 추출된다. 부글부글 소리가 나기 시작하면 커피향이 막 올라온다 >_<. 박스에 써있는 설명에는 치이익 소리가 나면서 추출될 꺼라는데 그냥 부글부글 소리만 난다. 일단 끓기 시작하면 아래 동영상 처럼 순식간에 추출된다. 신기하더라능. 

다 추출되면 잔에 따라서 마시면 된다! d>_<.b

 

저작자 표시 비영리 동일 조건 변경 허락

'뻘글들' 카테고리의 다른 글

모카포트 사용기 - 간편하게 집에서 마시는 에스프레소  (4) 2012/03/29
80000 hit  (1) 2011/09/24
FreeRTOS port of OpenRISC  (2) 2011/08/01
요즘 하고 있는 것  (2) 2011/07/25
GDB Reverse debugging  (0) 2011/07/21
How to install Boost Library in Mingw  (0) 2011/05/16

댓글을 달아 주세요

  1. clique 2012/04/01 03:39  댓글주소  수정/삭제  댓글쓰기

    으..귀찮아 보인다. 그냥 귀차니스트에겐 캡슐커피 머신이 짱이라능...!!

  2. sloth 2012/04/02 21:12  댓글주소  수정/삭제  댓글쓰기

    홈뿔라스에서 서버도 간편하게 장을볼수있냐능???? 얼마쯤 하면 하나 업어오냐능!!!!!

크리에이티브 커먼즈 라이선스
Creative Commons License

다른걸 해보기 전에 연습삼에서 C++로 간단하게 구현해 봤다. MVC에 관한건 http://www.filepang.co.kr/49 여기에 가면 좋은 글들이 많이 링크되어 있으니 그걸 읽어보자.

자질구래한 내용을 쓰고 싶진 않으니 코드만 올린다능.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
#ifndef __OBSERVER_HPP__
#define __OBSERVER_HPP__

class Observer 
{
	public: 
		virtual void update(void *) = 0;
}; 

#endif  // __OBSERVER_HPP__

#ifndef __OBSERABLE_HPP__
#define __OBSERABLE_HPP__

#include <vector> 

class Observable 
{ 
	public:
		Observable()
		{
			changed = false;
		}

		virtual ~Observable()
		{
			// do nothing
		}

		bool addObserver(Observer *a)
		{
			// check observer is valid
			if(a == NULL)
				return false;

			// don't add and observer more than once.
			for(std::vector<Observer*>::const_iterator observer_iterator=observers.begin(); 
					observer_iterator != observers.end(); 
					observer_iterator++ ) {
				if((*observer_iterator) == a) 
					return false;
			}

			// put observer into the list
			observers.push_back(a);

			return true;
		}

		void removeObserver(Observer *a)
		{
			// check observer is valid
			if(a == NULL)
				return;

			for(std::vector<Observer *>::iterator observer_iterator = observers.begin(); 
					observer_iterator != observers.end(); 
					observer_iterator++ ) {
				if(*observer_iterator == a) {
					observer_iterator = observers.erase(observer_iterator);
					return;
				}
			}
		}

		// notifyObservers 
		void notifyObservers(void *info)
		{ 
			// check info is valid
			if(info == NULL)
				return;
			
			// do nothing when observable is not changed
			if(!isChanged())
				return;

			for(std::vector<Observer *>::const_iterator observer_iterator = observers.begin(); 
					observer_iterator != observers.end(); 
					observer_iterator++ ) {
				(*observer_iterator)->update(info);
			}

			clearChanged();
		} 

		bool isChanged(void)
		{
			return changed;
		}

		size_t countObserver(void)
		{
			return observers.size();
		}

		void setChanged(void)
		{
			changed = true;
		}

		void clearChanged(void)
		{
			changed = false;
		}

	private:
		std::vector<Observer *>observers; 	// observer list 
		bool changed;
}; 

#endif  // __OBSERABLE_HPP__

#ifndef __ABSTRACTCONTROLLER_HPP__
#define __ABSTRACTCONTROLLER_HPP__

// #include "Observer.hpp"

class AbstractView;

class AbstractController 
{
	public:
		AbstractController()
		{
			// do nothing
		}

		AbstractController(Observable *m) : model(m)
		{
			// do nothing
		}

		virtual ~AbstractController()
		{
			// do nothing
		}

		void setModel(Observable *m)
		{
			model = m;
		}

		Observable *getModel(void)
		{
			return model;
		}

		void setView(AbstractView *v)
		{
			view = v;
		}

		AbstractView *getView(void)
		{
			return view;
		}

	protected:
		Observable *model;
		AbstractView *view;
};

#endif  // __ABSTRACTCONTROLLER_HPP__

#ifndef __ABSTRACTVIEW_HPP__
#define __ABSTRACTVIEW_HPP__

// #include "Observable.hpp"
// #include "Observer.hpp"
// #include "AbstractController.hpp"

class AbstractView : public Observer
{
	public:
		AbstractView()
		{
			// do nothing
		}

		AbstractView(Observable *m, AbstractController *c) : model(m), controller(c)
		{
			// do nothing
		}

		virtual ~AbstractView()
		{
			// do nothing
		}

		void setModel(Observable *m)
		{
			model = m;
		}

		Observable *getModel(void)
		{
			return model;
		}

		void setController(AbstractController *c)
		{
			controller = c;
			controller->setView(this);
		}

		AbstractController *getController(void)
		{
			return controller;
		}

	protected:
		Observable *model;
		AbstractController *controller;

};

#endif  // __ABSTRACTVIEW_HPP__

#include <cstdio>
#include <unistd.h>
// #include "mvc.hpp"

struct ClockModelInfo
{
	ClockModelInfo(int h, int m, int s) :
		  hour(h)
		, minute(m)
		, second(s)
	{
		// do nothing
	}

	int hour;
	int minute;
	int second;
};

class ClockModel : public Observable
{
	public:
		ClockModel()
		{
			hour = 0;
			minute = 0;
			second = 0;
		}

		virtual ~ClockModel()
		{
			// do nothing
		}

		void setHour(int h)
		{
			hour = h;
			notify();
		}

		void setMinute(int m)
		{
			minute = m;
			notify();
		}

		void setSecond(int s)
		{
			second = s;
			notify();
		}

		int getHour(int h)
		{
			return hour;
		}

		int getMinute(int m)
		{
			return minute;
		}

		int getSecond(int s)
		{
			return second;
		}

		void incHour(void)
		{
			hour += 1;
			if(hour >= 24) {
				hour = 0;
			}

			notify();
		}

		void incMinute(void)
		{
			minute += 1;
			if(minute >= 60) {
				minute = 0;
				incHour();
			}

			notify();
		}

		void incSecond(void)
		{
			second += 1;
			if(second >= 60) {
				second = 0;
				incMinute();
			}

			notify();
		}
	
	private:
		void notify(void)
		{
			setChanged();

			ClockModelInfo info(hour, minute, second);
			notifyObservers(&info);
		}

		int hour;
		int minute;
		int second;
};

class ClockView : public AbstractView
{
	public:
		ClockView()
		{
			// do nothing
		}

		virtual ~ClockView()
		{
			// do nothing
		}

		void update(void *info)
		{
			int hour = static_cast<ClockModelInfo *>(info)->hour;
			int minute = static_cast<ClockModelInfo *>(info)->minute;
			int second = static_cast<ClockModelInfo *>(info)->second;

			std::printf("\r%02d:%02d:%02d", hour, minute, second); 
			std::fflush(stdout);
		}
};

class ClockController : public AbstractController
{
	public:
		ClockController()
		{
			// do nothing
		}

		virtual ~ClockController()
		{
			// do nothing
		}

		int run(void)
		{
			while(1) {
				sleep(1);
				static_cast<ClockModel *>(model)->incSecond();
			}

			std::printf("\n");
			return 0;
		}
};

class ClockApplication
{
	public:
		explicit ClockApplication()
		{
			model.addObserver(&view);
			model.setHour(0);
			model.setMinute(0);
			model.setSecond(0);

			view.setModel(&model);
			view.setController(&controller);

			controller.setModel(&model);
		}

		virtual ~ClockApplication()
		{
			// do nothing
		}

		int run(int argc, char **argv)
		{
			return controller.run();
		}
	
	private:
		ClockModel model;
		ClockView view;
		ClockController controller;
};

int main(int argc, char **argv)
{
	ClockApplication app;

	return app.run(argc, argv);
}


저작자 표시 비영리 동일 조건 변경 허락

'객체지향 프로그래밍 > 디자인 페턴' 카테고리의 다른 글

C++ Simple MVC example  (0) 2012/02/25
ruby EventDispatcher  (0) 2011/11/06
Thread Pool  (6) 2009/04/10
Object Pool  (11) 2009/03/08
MVC(Model-View-Controller) 디자인 패턴에 대한 좋은 아티클들  (6) 2008/08/08

댓글을 달아 주세요

Wishbone SSRAM controller

베릴로그 | 2012/01/04 22:49 | Posted by DMW
크리에이티브 커먼즈 라이선스
Creative Commons License
모종의 이유로 16비트 SSRAM 컨트롤러를 만들고 있었는데 이미 매우 잘 만들어 진것이 있어서 만들다 말았다. 그 만들다 만 결과물을 올린다능. 만들다 말아서 시뮬레이션 까지만 검증이 되었다. 블로그가 말라 죽을꺼 같아서 올렸봤다. 스펙은 다음과 같다.

support 32bit Wishbone interface
support only 16bit SSRAM
support single word, half-word, byte access
does not support Wishbone burst operation

아래 코드를 내려받고 sim 디렉토리 아래로 찾아가서 make 하면 돌려볼 수 있다.



저작자 표시 비영리 동일 조건 변경 허락

'베릴로그' 카테고리의 다른 글

Wishbone SSRAM controller  (5) 2012/01/04
Clock speed  (0) 2011/05/02
Verilog VPI example  (2) 2011/03/21
Verilog Coding Guidelines  (2) 2010/12/11
베릴로그 스니펫 Resettable D flip-flop  (3) 2010/11/14
베릴로그 스니펫 D flip-flop, Verilog D flip-flop  (0) 2010/11/13

댓글을 달아 주세요

  1. prismatic 2012/01/14 03:20  댓글주소  수정/삭제  댓글쓰기

    헐 성님! ㄷㅁㅇ 성님! ㅠㅜ
    공부자료 생겼네 ㅠㅜ

  2. 2012/02/10 14:11  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

크리에이티브 커먼즈 라이선스
Creative Commons License
 
module EventDispatcher
	def setup_listeners
		@listeners = {}
		@change = false
	end

	def register_listener(listener, event)
		(@listeners[event] ||= []) << listener
	end

	def remove_listener(listener, event)
		(@listeners[event] ||= []).delete listener
	end

	def remove_listeners(event)
		@listeners[event] = []
	end

	def count_listeners(event)
		(@listeners[event] ||= []).size
	end

	def changed?
		@change
	end

	protected
	def notify(event, arg)
		return if not @change
		if @listeners[event]
			callback = ("update_at_" + event.to_s).to_sym
			@listeners[event].each do |listener|
				if listener.respond_to? callback
					listener.send callback, arg
				elsif listener.respond_to? :update
					listener.update event, arg
				end
			end
		end
		@change = false
		return nil	
	end

	def changed
		@change = true
	end
end	

class TestFactory
	include EventDispatcher
	
	def initialize
		setup_listeners
	end	

	def create_button(color)
		changed
		notify(:new_button, {:color => color})
	end

	def create_label(text)
		changed
		notify(:new_label, {:text => text})
	end
end

class TestWidgetCounter
	def initialize(widget_factory)
		@counts = Hash.new(0)
		widget_factory.register_listener(self, :new_button)
		widget_factory.register_listener(self, :new_label)
	end

	def update(event, arg)
		case event
		when :new_label
			puts "#{arg[:text]} label created."
		end	
	end

	def update_at_new_button(arg)
		color = arg[:color]
		@counts[color] += 1
		puts "#{@counts[color]} #{color} button(s) created."
	end
end



f = TestFactory.new
t = TestWidgetCounter.new(f)

f.create_button("red")
f.create_button("blue")
f.create_button("green")
f.create_label("name")
f.create_button("red")

f.remove_listener(t, :new_label)
f.create_label("cellphone")

f.create_button("blue")


Output:
1
2
3
4
5
6
1 red button(s) created.
1 blue button(s) created.
1 green button(s) created.
name label created.
2 red button(s) created.
2 blue button(s) created.


APE 0.50a 포팅할 때 사용하려고 만들었던 EventDispatcher
저작자 표시 비영리 동일 조건 변경 허락

'객체지향 프로그래밍 > 디자인 페턴' 카테고리의 다른 글

C++ Simple MVC example  (0) 2012/02/25
ruby EventDispatcher  (0) 2011/11/06
Thread Pool  (6) 2009/04/10
Object Pool  (11) 2009/03/08
MVC(Model-View-Controller) 디자인 패턴에 대한 좋은 아티클들  (6) 2008/08/08

댓글을 달아 주세요