유니티를 사용하다 보면 디버깅을 위해 로그를 찍을때 리스트 뷰에서는 콜스택에 대한 정보를 볼수 없어 귀찮은 경우가 많다. 어셋 스토에서 판매하고 있는 'Console Pro'라는 어셋을 사용하면 편리하긴하지만..

using UnityEngine;


public static class LogHeader

{

    public static string Path

    {

        get

        {

#if UNITY_EDITOR || USE_DEBUGGING

            string callStack = StackTraceUtility.ExtractStackTrace();

            callStack = callStack.Substring(callStack.IndexOf("\n") + 1);

            callStack = callStack.Substring(0, callStack.IndexOf("\n") + 1);

            return callStack;

#else

            return "";

#endif

        }

    }


    public static string Function

    {

        get

        {

#if UNITY_EDITOR || USE_DEBUGGING

            string callStack = StackTraceUtility.ExtractStackTrace();

            callStack = callStack.Substring(callStack.IndexOf("\n") + 1);

            callStack = callStack.Substring(0, callStack.IndexOf("("));

            //callStack = callStack.Substring(0, callStack.IndexOf(" ") + 1);

            return "[" + callStack + "] ";

#else

            return "";

#endif

        }

    }


    // example :

    //     Debug.Log(LogHeader.Function + "any log text will be here");

    // result :

    //    CallStackLogMain:func_2() (at Assets/CallStackLogMain.cs:17)

    //    any log text will be here

}



Posted by kukuta
TAG C#, unity

댓글을 달아 주세요

1. jQuery CDN 연결

jQuery 자바스크립트를 다운 받고 서버에 다시 올리기 귀찮으니 구글과 MS에서 제공하는 CDN(Content Delivery Network)을 사용하도록 하자 :

Google CDN :

<head>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

</head>


Microsft CDN :

<head>

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>

</head>



2. jQuery 문법 기본

$(selector).action()

  • '$' : jQuery를 사용하겠다는 선언
  • (selector) : html 엘리먼트를 찾고 접근하기 위한 selector
  • action() : 엘리먼트에 수행할 작업
  • jQuery selector는 css selector방식을 사용하고 있음. [진리는어디에/Web] - CSS Selectors 를 참고.
  • eg :
    • $(this).hide() - 현재 엘리먼트를 보이지 안도록 감추다
    • $("p").hide() - <p> 엘리먼트는 모두 보이지 않도록 감추다.
    • $(".test").hide() - class="test" 인 모든 엘리먼트를 보이지 않도록 감추다.
    • $("#test").hide() - id="test" 인 모든 엘리먼트를 보이지 않도록 감추다.

3. jQuery 시작

$(document).Ready(function() {

  // ...

});



jQuery Event

$(selector).click(function() {

});

* manual : https://www.w3schools.com/Jquery/jquery_events.asp

* reference : https://www.w3schools.com/Jquery/jquery_ref_events.asp


jQuery Effect :

$(selector).hide();

* manual : https://www.w3schools.com/Jquery/jquery_hide_show.asp

* reference : https://www.w3schools.com/Jquery/jquery_ref_effects.asp


jQuery HTML :

text() - Sets or returns the text content of selected elements

html() - Sets or returns the content of selected elements (including HTML markup). 위에꺼에 html도 같이 포함해서 리턴한다.

val() - Sets or returns the value of form fields. form에서 value에 매핑 된 값만 리턴한다.

attr() method is used to get attribute values.


append() - Inserts content at the end of the selected elements

 eg) ol 태그에 하위 li 태그를 append 할 수 있다

prepend() - Inserts content at the beginning of the selected elements

after() - Inserts content after the selected elements

before() - Inserts content before the selected elements


remove() - Removes the selected element (and its child elements)

empty() - Removes the child elements from the selected element


jQuery Traversing

* first()

* last()

* eq()

* filter() : https://www.w3schools.com/Jquery/jquery_filters.asp

* not()

* find()


jQuery AJAX(Asynchronous JavaScript and XML.)

* $(selector).load() : https://www.w3schools.com/Jquery/jquery_ajax_load.asp

* $.get(URL, callback)/$.post(URL, data, callback) : https://www.w3schools.com/Jquery/jquery_ajax_get_post.asp

* reference : https://www.w3schools.com/Jquery/jquery_ref_ajax.asp


Posted by kukuta

댓글을 달아 주세요

사전적 의미의 delegate는 '대리자'로써 뭔가를 대신 해준다는 의미고, C#에서의 delegate는 일종의 콜백 함수 '리스트'로써 입력과 출력이 동일한 함수들을 일괄 호출하는데 사용된다.


이게 C++ 관점에서 보면 함수 포인터 리스트를 들고 있는 간단한 클래스 정도인데, 개념적으로도 어렵지 않고 구현하는 것도 그렇게 어렵지 않다. 말 그대로 함수 포인터 리스트를 만들어도 되고, 인터페이스 클래스를 정의하고 그걸 상속 받은 클래스 리스트를 만들어도 된다. 다만...필요할때 마다 매번 만드는게 은근 귀찮아 template과 operator overriding을 이용하여 재사용 가능한 delegate 클래스를 만들어 보도록 하겠다(c++ 11 이상).


우선 C# delegate의 인터페이스를 살펴 보면 :

  • 콜백 함수를 등록하기 위한 operator '+='
  • 등록된 콜백 함수를 제거하기 위한 operator '-='
  • 등록된 콜백 함수를 개별로 호출 하기 위한 iterate 인터페이스
정도로 정리가 된다.

이 포스트에서는 전체 코드는 살펴 보지 않고 부분 별 구현 내용만 살짝씩 살펴 볼 예정이다. 전체 코드는 다음 링크를 타고가면 된다(전체 코드 보기 : https://github.com/ChoiIngon/gamnet/blob/master/Gamnet/Library/Delegate.h)

클래스 선언 :
template <class T> class Delegate; /* undefiend */
template <class R, class... ARGS> class Delegate<R(ARGS...)>
template <class... ARGS> class Delegate<void(ARGS...)>
기본적으로 std::function과 비슷한 문법으로 사용하기 위해서 템플릿 특수화를 적용했다. 선언만 하고 정의는 구현되지 않은 기본 클래스를 만들고, 그 후 템플릿 특수화가 적용된 Delegate 클래스를 선언한다. std::function 처럼 사용 할 수 있도록 '리턴타입(인자 리스트)' 와 같은 형태로 선언하는데 여기서 눈여겨 봐야 할 부분은 리턴 타입이 void 형인지 아닌지에 따라 특수화를 나눴다는 것이다. 콜백 함수 리스트를 호출하는 부분에서 리턴 타입에 따라 구현이 달라져야 하기 때문에 클래스 자체를 템플릿 특수화를 통해 구분했다.


함수 포인터 리스트 :

std::list<std::function<R(ARGS...)>> funcs;

일반 함수 포인터 뿐만 아니라 클래스 멤버 함수도 저장 할수 있도록 std::function 리스트를 사용 했다.


operator += : 

Delegate<R(ARGS...)>& operator += (std::function<R(ARGS...)> const& arg)

...자세한 설명은 생략한다...


operator -= :

기존에 등록된 함수 포인터 주소를 비교하여 리스트에서 삭제해주는 오퍼레이터다. std::function::target 템플릿 멤버 함수를 사용하는데 여기서 주의 해야 할 부분이 템플릿 클래스의 템플릿 멤버 함수를 호출하게 되면 컴파일러가 타입을 제대로 추론하지 못해 템플릿 멤버 함수에 대해서 컴파일 오류를 발생 시킨다. 이럴 경우 명시적으로 템플릿 함수라는 것을 지정하기 위해 함수의 호출 부 앞에 'template' 키워드를 붙여 준다.

Delegate<R(ARGS...)>& operator -= (std::function<R(ARGS...)> const& arg)

{

R (*const* ptr)(ARGS...) = arg.template target<R(*)(ARGS...)>();

...

참고 : [진리는어디에] - 'template' 키워드를 한정자로 사용하기(C++)


사용 :

#include <iostream>


int f_1(int a, int b)

{

return a + b;

}


int g_1(int a, int b)

{

return a - b;

}


void f_2(int a, int b)

{

std::cout << a + b << std::endl;

}


void g_2(int a, int b)

{

std::cout << a - b << std::endl;

}


int main()

{

Delegate<int(int, int)> delegate_1;

delegate_1 += f_1;

delegate_1 += g_1

std::cout << delegate_1(100, 10) << std::endl; // print 90 only


for(auto itr=delegate_1.begin(); itr != delegate_1.end(); itr++)

{

std::cout << (*itr)(100, 10) << std::endl; // print 110 and 90

}


Delegate<void(int, int)> delegate_2;

delegate_2 += f_2;

delegate_2 += g_2

delegate_1(100, 10); // print 110 and 90


return 0;

}


기본적으로 위와 같이 구현 되어 있고 설명에 언급 되지 않은 것은 리턴 타입이 void인 경우를 위한 클래스를 하나 더 만든 부분이다.


전체 코드 보기 : https://github.com/ChoiIngon/gamnet/blob/master/Gamnet/Library/Delegate.h


Posted by kukuta

댓글을 달아 주세요

  1. Favicon of http://tood-re.tistory.com BlogIcon 먹튀 검증 2018.08.02 14:04 신고  댓글주소  수정/삭제  댓글쓰기

    잘보고갑니다~