Maxscript 스레드 함수에 파라미터 받기

 

 

지난번에 Maxscript에서 스레드를 분리해서 작업하는 방법을 이야기 했었습니다.

이번에는 스레드 함수에 파라미터를 받는 방법에 대해 알아보도록 하겠습니다.

 

Struct로 Class?와 비슷한 기능을 하는 방법을 이용 할 건데요.

Struct를 굳이 이용하는 이유는..

Maxscript에 이런저런 기능을 넣다 보면, 필요할 때마다 꺼내 쓰고 싶어집니다.

매번 만드는 것도 즐거운 일은 아니잖아요~

그렇다고 Start함수에 사용하는 모든 함수를 등록해두는 건 좋은방법은 아닐 것 같습니다.

등록한 함수가 10개 미만이면  괜찮으나, 그 수가 점점 늘어나게 되면 감당하기 힘들어 집니다.

이럴 때 Struct를 이용해 기능 별로 함수를 묶어 사용하면 편하고 좋습니다.

서론이 길었군요.

 

스레드 함수는 일반 함수처럼 파라미터를 받을 수 없습니다.

fn aFn a b =() 이런게 안된다는 거죠.

그렇다보니 다른 방법을 이용해야 합니다.

 

여기서 이야기 할 방법은 2가지 인데요.

DoWorkEventArgs와 변수를 이용하는 방법을 이야기해 보겠습니다.

 

 

Struct안에서 파라미터 넘기기

(
------------------------------------------------------------------------------------------------------------
--  ThreadClass
------------------------------------------------------------------------------------------------------------
struct ThreadClass
(
 -- Public ============================================================================
 Public
 --====================================================================================
 --------------------------------------------------------------------
 -- BackGroundWorker
 --------------------------------------------------------------------
 fn BackGroundWorker theFn argument:1 =
 (
  dno_BackGroundWorker = dotNetObject "System.ComponentModel.BackGroundWorker"
  dno_BackGroundWorker.WorkerSupportsCancellation = true
  dotNet.addEventHandler dno_BackGroundWorker "DoWork" theFn
  dno_BackGroundWorker.RunWorkerAsync(argument) --argument는 간단한 값을 받을 수 있다.(struct나 object과 같은 Max전용은 사용 할 수 없다)
  
  return dno_BackGroundWorker
 )
)


------------------------------------------------------------------------------------------------------------
--  PlusClass
------------------------------------------------------------------------------------------------------------
struct PlusClass
(
 -- Public =============================================================================
 Public
 --====================================================================================
 --------------------------------------------------------------------
 --  Thread_PlusAtoB
 -------------------------------------------------------------------- 
 fn Thread_PlusAtoB e =
 (
  -- e : DoWorkEventArgs Thread에 넣은 Argument는 여기로 들어온다.
  total = 0
  for i = e.Argument[1] to e.Argument[2] do
  (
   sleep 0.02
   total += i
  )
  print total
 ),
 
 
 --------------------------------------------------------------------
 --  PlusAtoB
 --------------------------------------------------------------------
 fn PlusAtoB a b =
 (
  arg = #(a, b) -- Argument는 하나만을 넘길 수 있어 배열로 받는다
  Thread = ThreadClass() -- ThreadClass를 생성
  Thread.BackGroundWorker Thread_PlusAtoB argument:arg
 )
)

Plus = PlusClass()
total = Plus.PlusAtoB 1 100
"스레드 작동"
)

 

 

PlusAtoB 1 100

1 부터 100까지 더하는 함수인데요.

간단한 함수지만 기능 설명을 하려고 조금 길게 섰습니다.

따로 변수를 등록하지 않고, 바로 Struct안에서 파라미터를 받을 때 사용하는데요.

(스레스 사용법은 아래 게시물을 보시면 되니 패스)

또한 ThreadClass를 따로 생성해 다른 스크립트에서도 스레드를 불러 쓸 수 있습니다.

코드가 짧아지겠군요.

이 방법은 argument에 넣을 수 있는 값이 제한적입니다.

문자, 숫자, 배열 같은 DotNet과 같이 사용 할 수 있는 데이터 값만을 argument에 넣을 수 있습니다.

(Object, Struct의 변수 등은 넣을 수 없습니다.)

 

이런 경우에 2번 방법을 사용합니다.

 

 

Struct 외부에서 변수 받아오기

 

(
local aVal = 0
local bVal = 0

 
------------------------------------------------------------------------------------------------------------
--  PlusClass
------------------------------------------------------------------------------------------------------------
struct PlusClass
(
 -- Private =============================================================================
 Private
 --====================================================================================
 --------------------------------------------------------------------
 -- BackGroundWorker
 --------------------------------------------------------------------
 fn BackGroundWorker theFn =
 (
  dno_BackGroundWorker = dotNetObject "System.ComponentModel.BackGroundWorker"
  dno_BackGroundWorker.WorkerSupportsCancellation = true
  dotNet.addEventHandler dno_BackGroundWorker "DoWork" theFn
  dno_BackGroundWorker.RunWorkerAsync()
  
  return dno_BackGroundWorker
 ),
 
 
 -- Public =============================================================================
 Public
 --====================================================================================
 --------------------------------------------------------------------
 --  Thread_PlusAtoB
 -------------------------------------------------------------------- 
 fn Thread_PlusAtoB =
 (
  total = 0
  for i = aVal to bVal do
  (
   sleep 0.02
   total += i
  )
  print total
 ),
 
 
 --------------------------------------------------------------------
 --  PlusAtoB
 --------------------------------------------------------------------
 fn PlusAtoB a b =
 (
  aVal = a
  bVal = b
  
  BackGroundWorker Thread_PlusAtoB
 )
)

Plus = PlusClass()
total = Plus.PlusAtoB 1 100
"스레드 작동"
)

 

PlusClass외부에 있는 변수 aVal,bVal에서 값을 받아서 사용합니다.

이 방법은 argument의 제한적인 값이 아닌 Max데이터를 그대로 사용 할 수 있습니다.

하지만 이렇게 할 경우 Struct외에도 따로 변수를 가지고 있어야 합니다.

또한 Struct마다 스레드 코드가 들어가야 하죠.

 

 

2가지 방법 모두 장단점이 있습니다.

상황에 따라 적절하게 사용하세요.

 

Posted by Hwanggoon
,