특정 함수를 구현함에 있어 함수에서의 작업이 언제 끝날지 알수 없는 작업을 구현할 경우 무한루프를 사용하게 됩니다.,
무한루프 안에서 특정 작업이 마무리 되면 break 로 빠져 나오겠지만 어떠한 문제로 인해 작업이 진행되지 않고 계속 무한루프를 돌게 되는 경우가 았습니다. 이런경우 Timeout 기능을 넣어서 일정시간이 지나도 작업이 끝나지 않을경우 무한루프를 빠져 나오도록 프로그램을 구현합니다.
Timeout 기능은 여러 방법이 있지만 이번 포스팅에서는 Stopwatch 객체를 이용해서 구현해 보았습니다.
public int WorkFunction(int TimeOut)
{
int result = 0 ;
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); // stopwatch 객체 생성
sw.Start() ; // stopwatch 시작
try
{
while(true)
{
// workflow 구현
var time = (int)(sw.ElapsedMilliseconds / 1000);
if (time >= TimeOut) // Timeout 시간 경과
{
result = -1;
break;
}
}
}
finally
{
sw.Stop() ; // stopwatch 종료
}
return result ;
}
Flutter 공부한지 3일 만에 계산기 앱을 만들다 보니 너무 두서 없이 만들어 졌습니다. 앱을 만들어 가는 과정에서 MVVM 패턴이라던가 상태관리라는 것을 적용할 필요가 있다는 것을 알았습니다.
상태관리 package를 적용하여 프로그램을 수정하면서 이번 포스팅을 계속해야 하나 망설이다가 제어쪽 포스팅을 한참만에 올리게 되었습니다. 어차피 이번 포스팅은 초보자 관점에서 만들어 진것이니 제목 그대로 초보자가 만든 개념으로 포스팅은 마무리 하고 최종 수정된 프로그램은 별도로 공개 하는 방향으로 정하게 되었습니다.
그래서 이번에 최종적으로 계산기 제어 코드를 올리면서 아울러 상태관리와 함께 지난 포스팅에 빠져 있던 몇가지 버튼 기능들도 추가 하여 코드를 수정하고 공개 하게 되었습니다.
수정된 부분
1. MVVM 패턴 적용 : 파일도 패턴에 맞추어 분리 시키고 나름 MVVM 패턴을 적용해 보았습니다.
2. 상태관리 팩키지 적용 : 상태관리 패키지 2가지를 따로 따로 적용하여 코드를 만들어 보았습니다.
적용 패키지 (Provider, GetX )
3. 계산기의 몇가지 추가 버튼에 대한 기능을 추가 하였습니다.
코드는 GitHub 에 올려 놓았고 provider 과 GetX 두개로 Branche 시켜 두었습니다.
Main Branche 가 Provider 를 적용한 것이고 다른 하나는 GetX 입니다. 아래 Git 에서 소스 코드를 확인할 수 있습니다.
계산기 만들기 마지막 포스팅으로 실제 계산기의 버튼을 누르고 연산을 하는 부분의 코드를 만듭니다.
일단 컨트롤에 사용될 변수를 전역변수로 선언을 합니다. main 함수 위에 선언해 주시면 됩니다.
var displayNumber = '0';
var makeNumber = '' ;
var selectedOperator = '−';
var displayFontSize = 80.0 ;
var pointExist = false ;
var firstNumber = 0.0 ;
var secondNumber = 0.0 ;
var _disignPage = new DesignPage() ;
컨트롤은 크게 3개의 함수로 구성되어 있습니다.
1. 숫자키 입력 : 숫자키와 소숫점을 눌렀을 때 발생되는 알고리즘에 대한 함수 입니다. 숫자는 처음입력시에는 문자열의 형태로 저장을 하고 이후 연산할 때 double 형의 숫자로 변경하도록 프로그램 했습니다.
void _numberOnPressed(String st) // 숫자키 입력 이벤트 함수
{
bool inputAdd = true ;
if(makeNumber.length < 9) // 숫자는 9자리 까지만
{
if(st == '.') // 소숫점이 눌려졌을 경우
{
if(makeNumber.isEmpty == true)
{
makeNumber += '0.';
inputAdd = false ;
}
else
{
if(pointExist == true) inputAdd = false ; // 소숫점이 없을 경우만 추가
}
pointExist = true ;
}
else if(st == '0' && makeNumber.isEmpty == true) inputAdd = false;
if(inputAdd == true) makeNumber += st ;
displayNumber = makeNumber ;
if(displayNumber.length < 7) displayFontSize = 80.0 ; // 글자 크기를 선택
else displayFontSize = 50 ;
_disignPage.setState(() { displayNumber ;}); // 화면을 갱신한다.
}
}
//-----------------------------------------------------------------------------------------