LOGIN • JOININ

DEFAULT EXECUTOR

[Tutorials/[Common] 2. Execute system/Tutorial_Execute01_ExecutorSystem]



CGCII는 기본적인 동작을 위해 기본적인 Executor를 생성해 가지고 있습니다. 이를 Default Executor라고 합니다.

이 Default Executor 객체는 특별히 초기화하지 않아도 자동으로 생성되고 초기화되므로 언제든 사용할 수 있습니다.

이 Executor에 비동기 실행을 요청하는 함수가바로 'POST_EXECUTE(...)'함수 입니다.

아래의 예제는 'POST_EXECUTE(...)'의 사용 예를 보여줍니다.


POST_EXECUTE(...)는 정적 함수, 멤버함수, 람다함수, std::bind() 함수객체, ICGExecutable 객체 등을 모두 실행할 수 있습니다.

POST_EXECUTE(...)함수에 파라메터로 넘겨주면 자동적으로 판단해 실행해줍니다.


또 Scheduler와 연동해 특정한 시간에 실행하거나 주기적으로 실행이 가능합니다.

Scheduler와 연동해 주기적으로 실행하고자 한다면 REGISTER_SCHEDULE(...)함수로 간단히 처리할 수 있습니다.


Executable을 사용하기 위해서는 'CGExecuteClasses.h'를 Include해야 합니다.



1... 간단한 비동기 실행하기

람다함수(Lambda function)을 사용해 간단히 비동기 실행을 할수 있습니다.

POST_EXECUTE()함수를 사용해 Lambda로 작성된 함수를 기본 Executor에 실행을 겁니다.

int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
	// 비동기적으로 람다(Lambda)함수 실행 요청한다.
	POST_EXECUTE([=]()
	{
		printf("Hellow CGCII!!\n");
	});

	// ESC 누를 때까지 대기
	while(_getch()!=27);
}


2... 일반(정적) 함수의 비동기 실행하기

람다(Lambda)뿐만 아니라 일반(정적) 함수 역시 POST_EXECUTE()함수로 간단히 실행 처리할수 있습니다.

void foo()
{
	printf("Hellow CGCII!\n");
}

int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
	// 비동기 적으로 foo함수를 실행 요청한다.
	POST_EXECUTE(foo);

	// ESC 누를 때까지 대기
	while(_getch()!=27);
}



3... 정해진 시간에 비동기 실행하기

현재 시간에서 5초 후에 실행되게 하고 싶다면 아래와 같이 간단히 구현할수 있습니다. 

void foo()
{
	printf("Hellow CGCII!\n");
}

int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
	// @) 현재시간+5초 에 foo 함수를 실행하도록 요청 한다.
	POST_EXECUTE(foo, TICK::now()+TICK::seconds(5));

	// ESC 누를 때까지 대기
	while(_getch()!=27);
}

POST_EXECUTE(...)함수에 실행시간을 명시하면 Scheduler에 등록해 해당 시간에 Executor에 걸어 실행해줍니다.

만약 정해진 시간이 지났다면 즉시 실행됩니다.

Lambda함수든 전역함수든 멤버함수든 모두 가능합니다.



4... ICGExecutable

함수객체(Functor)를 만들어 Executor에 걸어 실행이 하면 ICGExecutable을 상속받아 ProcessExecute()함수에 실행 내역을 작성하면 됩니다.

// @1) ICGExecutable을 상속받는다.
class foo : virtual public ICGExecutable
{
public:
// @2) ProcessExecute 함수에 실행할 내용을 작성한다.
virtual	HRESULT ProcessExecute(_In_ uintptr_t p_Return, _In_ size_t p_Param) 
	{
		printf("Test A를 실행함(Return:%u, Transfered:%u)\n", p_Return, p_Param);

		return	S_OK;
	}
};

1) ICGExecutable 클래스를 상속받습니다..

2) ProcessExecute함수를 재정의 합니다.


이렇게 제작된 정의된 foo 클래스를 POST_EXECUTE로 기본 Executor에 실행을 걸게 되면 ProcessExecute()에 작성된 내용을 실행해 줍니다. 

int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
	// @1) 먼저 foo형으로 functor를 생성한다.
	CGPTR<foo>	pfunctor	 = NEW<foo>();

	// @) POST Executor에 즉시 걸어 즉시 실행한다.
	POST_EXECUTE(pfunctor);

	// @) 현재부터 5초후에 실행을 건다.
	POST_EXECUTE(pfunctor, TICK::now()+TICK::seconds(5));

	// ESC 누를 때까지 대기
	while(_getch()!=27);
}


5... ICGSchedulable

단발성 실행이 아니라 일정시간마다 주기적으로 실행해야 하는 일들이 있다면 단발로 걸어주는 것이 아니라  Schedulable를 사용해 간단히 구현가능합니다.

class foo : public CGSchedulable::NExecutable
{
public:
	// 1) 실행될 함수.
	virtual	HRESULT		ProcessExecute(_In_ uintptr_t , _In_ size_t) override
	{
		// - 출력
		printf("[A]");

		// Return) 
		return	S_OK;
	}
};

1) 일단 CGSchedulable::NExecutable을 상속받습니다.

2) CGSchedulable::NExecutable는 ICGExecutable과 ICGSchedulable를 모두 상속받은 클래스입니다.

3) 여기에서 ICGExecutable의 가상함수인 ProcessExecute()함수를 재정의합니다.


“[A]”가 찍히도록 작성되었습니다.


이렇게 작업된 foo 클래스의 객체를 Schedulable에 등록해 일정 시간마다 실행되게 하려면 아래와 같이 하면 됩니다.

int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
	// @1) 먼저 foo형으로 functor를 생성한다.
	CGPTR<foo>	pfunctor	 = NEW<foo>();

	// @2) 1초마다 실행되도록 설정한다.
	pfunctor ->SetExecuteInterval(TICK::seconds(1));

	// @3) Schedulable에 등록한다.
	REGISTER_SCHEDULABLE(pfunctor);

	// ESC를 누를 때까지 대기한다.
	while(_getch()!=27);

	// @4) Schedulable에서 떼낸다.
	UNREGISTER_SCHEDULABLE(pfunctor);
}

1) 가장 먼저 foo 클래스의 객체를 만듭니다.

2) SetExecuteInterval()함수를 사용해 실행 간격을 1초로 설정했습니다.

3) REGISTER_SCHEDULABLE()을 사용해 기본 Schedulabe에 등록합니다.

Scheduler에 등록하면 1초 가격마다 한번씩 실행되어 “[A]”가 출력될 것입니다.

4) UNREGISTER_SCHEDULABE()함수를 호출해 등록 해제할 수도 있습니다.



[Source]