问:
How to apply SVG clip path relative to origin SVG instead of target element
I am trying to apply an SVG clipPath to a separate background div which has fixed positioning. I would like the clip-path to remain at the exact location of the origin SVG element, and to accordingly move when scrolling (or otherwise transformed).

What is happening instead, is that the clip path is inserted relative to the target element's origin and loses all positioning, scrolling, and transforms. Is there a way to preserve origin properties and apply these to a separate div?

In the embedded snippet below, the blue circle is where I would like the clip-path to be, whereas the red circle is where it is showing up.

#container {
  clip-path: url(#myClip);
  position: fixed;
  width: 100vw;
  height: 100vh;
  background-color: red;
}

#offset-container {
  position: absolute;
  top: 200px;
  left: 200px;
  width: 200px;
  height: 200px;
  border-style: solid;
  border-color: blue;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id='container'>

</div>

<div id='offset-container'>
  <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <clipPath id="myClip">
      <circle cx="50%" cy="50%" r="50%"/>
    </clipPath>
  </defs>
  <circle cx="50%" cy="50%" r="50%" fill='blue' fill-opacity='0.5'/>
</svg>
</div></code>```

JSFiddle: https://jsfiddle.net/shongololo/pa0qLs45/1/

答:
This works (almost) in Firefox, but not in Chrome, where it shows a really strange bug.

You'll need two divs: The outer is positioned relative and defines the clip-path so it moves. The inner is positioned fixed. Apparently, the explicit setting of top/left/width/height is needed and then refers to viewport coordinates.

body { margin: 0 }

#container {
  position: relative;
  overflow: hidden;
  top: 202px; /* border! */
  left: 202px;
  clip-path: url(#myClip);
  width: 200px;
  height: 200px;
}

#fixed {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100vw;
  height: 100vh;
  background-color: red;
}

#offset-container {
  position: absolute;
  top: 200px;
  left: 200px;
  width: 200px;
  height: 200px;
  border: 2px solid blue;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id='container'>
    <div id="fixed"></div>
</div>

<div id='offset-container'>
  <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <clipPath id="myClip">
      <circle cx="50%" cy="50%" r="50%"/>
    </clipPath>
  </defs>
  <circle cx="50%" cy="50%" r="50%" fill='blue' fill-opacity='0.5'/>
</svg>
</div></code>```

Body:
I am trying to apply an SVG clipPath to a separate background div which has fixed positioning. I would like the clip-path to remain at the exact location of the origin SVG element, and to accordingly move when scrolling (or otherwise transformed).

What is happening instead, is that the clip path is inserted relative to the target element's origin and loses all positioning, scrolling, and transforms. Is there a way to preserve origin properties and apply these to a separate div?

In the embedded snippet below, the blue circle is where I would like the clip-path to be, whereas the red circle is where it is showing up.

#container {
  clip-path: url(#myClip);
  position: fixed;
  width: 100vw;
  height: 100vh;
  background-color: red;
}

#offset-container {
  position: absolute;
  top: 200px;
  left: 200px;
  width: 200px;
  height: 200px;
  border-style: solid;
  border-color: blue;
}

  <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <clipPath id="myClip">
      <circle cx="50%" cy="50%" r="50%"/>
    </clipPath>
  </defs>
  <circle cx="50%" cy="50%" r="50%" fill='blue' fill-opacity='0.5'/>
</svg>

JSFiddle: https://jsfiddle.net/shongololo/pa0qLs45/1/

Body:
This works (almost) in Firefox, but not in Chrome, where it shows a really strange bug.

You'll need two divs: The outer is positioned relative and defines the clip-path so it moves. The inner is positioned fixed. Apparently, the explicit setting of top/left/width/height is needed and then refers to viewport coordinates.

body { margin: 0 }

#container {
  position: relative;
  overflow: hidden;
  top: 202px; /* border! */
  left: 202px;
  clip-path: url(#myClip);
  width: 200px;
  height: 200px;
}

#fixed {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100vw;
  height: 100vh;
  background-color: red;
}

#offset-container {
  position: absolute;
  top: 200px;
  left: 200px;
  width: 200px;
  height: 200px;
  border: 2px solid blue;
}

<div id='container'>
    <div id="fixed"></div>
</div>

<div id='offset-container'>
  <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <clipPath id="myClip">
      <circle cx="50%" cy="50%" r="50%"/>
    </clipPath>
  </defs>
  <circle cx="50%" cy="50%" r="50%" fill='blue' fill-opacity='0.5'/>
</svg>
</div>


来源: stackexchange

问:
How to time javascript actions so that they happen at the right order
I am trying to figure out how to time this for statement so it happens every second or so. What ends up happening is that the x prints 5 for all logs because the for loop is looping before the Timeout happens. How can I time the loops so every iteration happens after the setTimeout finishes.

for (x = 0; x < 5; x++) {
  var wait = setTimeout( function() {
    console.log(x,"x");
  }, 800);
}```

答:
I think this is what you're trying to do:

for (x = 0; x < 5; x++) {
  (function(n){setTimeout(()=>{console.log(n,"x");},800*n);})(x);
}```

ContentLicense: CC BY-SA 3.0


问:
Storing and retrieving Golang slice, struct and slice of struct in Postgresql
Let say I have a table named PEOPLE which store rows of Person. However, the Person contains slice, struct and slice of struct, i.e. the Superpower, Vehicle and FriendList fields respectively.

How should I store and retrieve those values in Postgresql with Golang? I can't find any practical tutorial related to this problem. Use custom data types, or JSON, or ORM method, or building custom functions to deal with these? Many opinions out there, but I still can't figure out a working way to solve this problem, please help.

I am using Ozzo-dbx , however, any solutions is welcome.

Can someone provides a working example? Sorry if this newbie question irritates you, but I already tried for few days, and keep failing... (T_T)

```<code>type Transport struct {
    Brand string
    Size  int
}

type Friend struct {
    Name         string
    IsProgrammer bool
}

type Person struct {
    ID         int
    Name       string
    Superpower []string   //slice
    Vehicle    Transport  //struct
    FriendList []Friend   //slice of struct
}
</code>```

答:
In most cases you should create separate tables for Superpowers, Vehicles, and Friends.

If the relationships between one of these tables and the People table is many-to-one or one-to-one you can add foreign keys to them. If the relationship is many-to-many you should create a linking table that will hold the fkeys of the related records.

To store the data you can insert/update each record individually with simple SQL query strings and database/sql.

After that you can create table views that would aggregate the data you want per one person into a single row so that you don't pollute your Go code with complex SQL strings. Then you define simple SQL select query strings in Go and execute them with database/sql.

Body:
Let say I have a table named PEOPLE which store rows of Person. However, the Person contains slice, struct and slice of struct, i.e. the Superpower, Vehicle and FriendList fields respectively.

How should I store and retrieve those values in Postgresql with Golang? I can't find any practical tutorial related to this problem. Use custom data types, or JSON, or ORM method, or building custom functions to deal with these? Many opinions out there, but I still can't figure out a working way to solve this problem, please help.

I am using Ozzo-dbx , however, any solutions is welcome.

Can someone provides a working example? Sorry if this newbie question irritates you, but I already tried for few days, and keep failing... (T_T)

type Transport struct {
    Brand string
    Size  int
}

type Friend struct {
    Name         string
    IsProgrammer bool
}

type Person struct {
    ID         int
    Name       string
    Superpower []string   //slice
    Vehicle    Transport  //struct
    FriendList []Friend   //slice of struct
}


问:
How do I display multiple textfields to my labels?
I'm not sure if how I worded the question makes much sense so let me summarize.

I have 2 UITexfields and 2 UILabels.

I have it all working properly in terms of when I type into my first textField and hit return it will display my text.

Now I'm not sure how to get the same to apply to my other TextField and Label. I read that if I apply a tag to my textfield in Xcode "1" that I can apply tag "2" to my other textfield.

Here is the code I am using so when I press return it'll display textfield tag "1".

```<code>func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if textField.tag == 1 {
        nameDisplay?.text = textField.text!
    }

    return true
}
</code>```

So to completely round this out, I want to display both separate textfields on each separate label.

答:
Simply add an else to your if.

```<code>if textField.tag == 1 {
    nameDisplay.text = textField.text
} else {
    otherLabel.text = textField.text
}
</code>```

Please note you do not need the ? or ! in that code.

Another option, if you have outlets for your text fields, is to do the following instead of bothering with tags:

```<code>if textField == someTextFieldOutlet {
    nameDisplay.text = textField.text
} else {
    otherLabel.text = textField.text
}
</code>```

where someTextFieldOutlet is obviously needs to be the actual name of the appropriate text field outlet you have.

Body:
I'm not sure if how I worded the question makes much sense so let me summarize.

I have 2 UITexfields and 2 UILabels.

I have it all working properly in terms of when I type into my first textField and hit return it will display my text.

Now I'm not sure how to get the same to apply to my other TextField and Label. I read that if I apply a tag to my textfield in Xcode "1" that I can apply tag "2" to my other textfield.

Here is the code I am using so when I press return it'll display textfield tag "1".

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if textField.tag == 1 {
        nameDisplay?.text = textField.text!
    }

    return true
}

So to completely round this out, I want to display both separate textfields on each separate label.

Body:
Simply add an else to your if.

if textField.tag == 1 {
    nameDisplay.text = textField.text
} else {
    otherLabel.text = textField.text
}

Please note you do not need the ? or ! in that code.

Another option, if you have outlets for your text fields, is to do the following instead of bothering with tags:

if textField == someTextFieldOutlet {
    nameDisplay.text = textField.text
} else {
    otherLabel.text = textField.text
}

where someTextFieldOutlet is obviously needs to be the actual name of the appropriate text field outlet you have.


问:
RecyclerView reverse endless scrolling
I'm creating a chat app and I am trying to implement endless scrolling for RecyclerView in a reversed manner, like start from the bottom and scroll up, when top is reached, load more.

When the user opens the chat screen, the app gets the last 20 messages and scrolls to the bottom by default. I want to get more messages from the server as the user scrolls up.

The following is just a generic endless scrolling code i am testing with:

```<code>protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layoutManager = new LinearLayoutManager(this);
        recyclerView =  (RecyclerView)findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);

        adapter = new RecyclerViewAdapter<String, ItemViewHolder>(String.class,R.layout.item,ItemViewHolder.class,list) {
            @Override
            protected void populateViewHolder(ItemViewHolder viewHolder, String model, int position) {
                if(model != null){
                    viewHolder.textView.setText(model);
                }
            }
        };
        recyclerView.setAdapter(adapter);
        recyclerView.setOnScrollListener(new EndlessReverseRecyclerViewScrollListener(layoutManager) {
            @Override
            public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                loadMore();
            }
        });
        loadInit();
    }

    private void loadInit(){
        for(int x = 0; x < 20;x++){
            list.add(list.size()+": "+getRandomString(8));
            adapter.notifyDataSetChanged();
        }
        layoutManager.scrollToPosition(list.size() -1);
    }

    private void loadMore(){
        for(int x = 0; x < 20;x++){
            list.add(list.size()+": "+getRandomString(8));
            adapter.notifyDataSetChanged();
        }
    }
</code>```

endless scrolling class

```<code>public EndlessReverseRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
        this.layoutManager = layoutManager;
    }

    // This happens many times a second during a scroll, so be wary of the code you place here.
    // We are given a few useful parameters to help us work out if we need to load some more data,
    // but first we check if we are waiting for the previous load to finish.
    @Override
    public void onScrolled(RecyclerView view, int dx, int dy) {
        int lastVisibleItemPosition = 0;
        int totalItemCount = layoutManager.getItemCount();

        if (layoutManager instanceof StaggeredGridLayoutManager) {
            int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(null);
            // get maximum element within the list
            lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
        } else if (layoutManager instanceof GridLayoutManager) {
            lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
        } else if (layoutManager instanceof LinearLayoutManager) {
            lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
        }

        Log.d(TAG," *** last visible: "+lastVisibleItemPosition);
        Log.d(TAG," *** total: "+totalItemCount);
        // If the total item count is zero and the previous isn't, assume the
        // list is invalidated and should be reset back to initial state
        if (totalItemCount < previousTotalItemCount) {
            this.currentPage = this.startingPageIndex;
            this.previousTotalItemCount = totalItemCount;
            if (totalItemCount == 0) {
                this.loading = true;
            }
        }
        // If it’s still loading, we check to see if the dataset count has
        // changed, if so we conclude it has finished loading and update the current page
        // number and total item count.
        if (loading && (totalItemCount > previousTotalItemCount)) {
            loading = false;
            previousTotalItemCount = totalItemCount;
        }

        // If it isn’t currently loading, we check to see if we have breached
        // the visibleThreshold and need to reload more data.
        // If we do need to reload some more data, we execute onLoadMore to fetch the data.
        // threshold should reflect how many total columns there are too
        if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
            currentPage++;
            onLoadMore(currentPage, totalItemCount, view);
            loading = true;
        }
    }

    // Call this method whenever performing new searches
    public void resetState() {
        this.currentPage = this.startingPageIndex;
        this.previousTotalItemCount = 0;
        this.loading = true;
    }

    // Defines the process for actually loading more data based on page
    public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);
</code>```

This works perfectly for scrolling from top to bottom, Can someone please assist on how I can make it work from bottom to top. Thanks

P.S. ReverseLayout is not the solution I'm looking for because it just reverses the order of my items and that's not what I am trying to achieve.

答:
The reverseLayout property on a RecyclerView's LayoutManager will do what you want.

Kotlin:

```<code>myRecyclerView.layoutManager = LinearLayoutManager(
    context = this,
    orientation = LinearLayoutManager.VERTICAL,
    reverseLayout = true
).apply { stackFromEnd = true }
</code>```

XML:

```<code><androidx.recyclerview.widget.RecyclerView
    ...
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    app:reverseLayout="true"
    app:stackFromEnd="true"
    android:orientation="vertical />
</code>```

You can set stackFromEnd to false if you don't want your items to stack from bottom.

Title: RecyclerView reverse endless scrolling

Body:
I'm creating a chat app and I am trying to implement endless scrolling for RecyclerView in a reversed manner, like start from the bottom and scroll up, when top is reached, load more.

When the user opens the chat screen, the app gets the last 20 messages and scrolls to the bottom by default. I want to get more messages from the server as the user scrolls up.

The following is just a generic endless scrolling code i am testing with:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layoutManager = new LinearLayoutManager(this);
        recyclerView =  (RecyclerView)findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);

        adapter = new RecyclerViewAdapter<String, ItemViewHolder>(String.class,R.layout.item,ItemViewHolder.class,list) {
            @Override
            protected void populateViewHolder(ItemViewHolder viewHolder, String model, int position) {
                if(model != null){
                    viewHolder.textView.setText(model);
                }
            }
        };
        recyclerView.setAdapter(adapter);
        recyclerView.setOnScrollListener(new EndlessReverseRecyclerViewScrollListener(layoutManager) {
            @Override
            public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                loadMore();
            }
        });
        loadInit();
    }

    private void loadInit(){
        for(int x = 0; x < 20;x++){
            list.add(list.size()+": "+getRandomString(8));
            adapter.notifyDataSetChanged();
        }
        layoutManager.scrollToPosition(list.size() -1);
    }

    private void loadMore(){
        for(int x = 0; x < 20;x++){
            list.add(list.size()+": "+getRandomString(8));
            adapter.notifyDataSetChanged();
        }
    }

endless scrolling class

public EndlessReverseRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
        this.layoutManager = layoutManager;
    }

    // This happens many times a second during a scroll, so be wary of the code you place here.
    // We are given a few useful parameters to help us work out if we need to load some more data,
    // but first we check if we are waiting for the previous load to finish.
    @Override
    public void onScrolled(RecyclerView view, int dx, int dy) {
        int lastVisibleItemPosition = 0;
        int totalItemCount = layoutManager.getItemCount();

        if (layoutManager instanceof StaggeredGridLayoutManager) {
            int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(null);
            // get maximum element within the list
            lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
        } else if (layoutManager instanceof GridLayoutManager) {
            lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
        } else if (layoutManager instanceof LinearLayoutManager) {
            lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
        }

        Log.d(TAG," *** last visible: "+lastVisibleItemPosition);
        Log.d(TAG," *** total: "+totalItemCount);
        // If the total item count is zero and the previous isn't, assume the
        // list is invalidated and should be reset back to initial state
        if (totalItemCount < previousTotalItemCount) {
            this.currentPage = this.startingPageIndex;
            this.previousTotalItemCount = totalItemCount;
            if (totalItemCount == 0) {
                this.loading = true;
            }
        }
        // If it’s still loading, we check to see if the dataset count has
        // changed, if so we conclude it has finished loading and update the current page
        // number and total item count.
        if (loading && (totalItemCount > previousTotalItemCount)) {
            loading = false;
            previousTotalItemCount = totalItemCount;
        }

        // If it isn’t currently loading, we check to see if we have breached
        // the visibleThreshold and need to reload more data.
        // If we do need to reload some more data, we execute onLoadMore to fetch the data.
        // threshold should reflect how many total columns there are too
        if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
            currentPage++;
            onLoadMore(currentPage, totalItemCount, view);
            loading = true;
        }
    }

    // Call this method whenever performing new searches
    public void resetState() {
        this.currentPage = this.startingPageIndex;
        this.previousTotalItemCount = 0;
        this.loading = true;
    }

    // Defines the process for actually loading more data based on page
    public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);

This works perfectly for scrolling from top to bottom, Can someone please assist on how I can make it work from bottom to top. Thanks

P.S. ReverseLayout is not the solution I'm looking for because it just reverses the order of my items and that's not what I am trying to achieve.

Body:
The reverseLayout property on a RecyclerView's LayoutManager will do what you want.

Kotlin:

myRecyclerView.layoutManager = LinearLayoutManager(
    context = this,
    orientation = LinearLayoutManager.VERTICAL,
    reverseLayout = true
).apply { stackFromEnd = true }

XML:

<androidx.recyclerview.widget.RecyclerView
    ...
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    app:reverseLayout="true"
    app:stackFromEnd="true"
    android:orientation="vertical />

You can set stackFromEnd to false if you don't want your items to stack from bottom.

ContentLicense: CC BY-SA 4.0


问:
from TextRecognition to Loading a Scene using Unity and Vuforia
I'm working since 3 months with Unity engine and the last month I began to adding Vuforia capabilities to my Unity projects. Right now, I'm developing an application which comprises TextRecognition (Vuforia Prefab), see picture below. So, when the word "Unterwagen" is recognized, it should be load another scene that works perfectly. However, it should be a delay between this transition and I don't now how to do it. I would appreciate if someone can help me.

DefaultTrackableEvent.cs

```<code>    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.SceneManagement;

namespace Vuforia
{
    /// <summary>
    /// A custom handler that implements the ITrackableEventHandler interface.
    /// </summary>
    public class DefaultTrackableEventHandler1 : MonoBehaviour,
    ITrackableEventHandler
    {
        #region PRIVATE_MEMBER_VARIABLES

        private TrackableBehaviour mTrackableBehaviour;

        #endregion // PRIVATE_MEMBER_VARIABLES

        public GameObject _statusTxt;
        public AudioSource clickRight;
        public  AudioSource clickWrong;
        public Text text;

        #region UNTIY_MONOBEHAVIOUR_METHODS

        void Start()
        {

            mTrackableBehaviour = GetComponent<TrackableBehaviour>();
            if (mTrackableBehaviour)
            {
                mTrackableBehaviour.RegisterTrackableEventHandler(this);
            }

            text.text = "Auf der Suche nach der Unterwagen Schrift";
        }

        #endregion // UNTIY_MONOBEHAVIOUR_METHODS

        #region PUBLIC_METHODS

        /// <summary>
        /// Implementation of the ITrackableEventHandler function called when the
        /// tracking state changes.
        /// </summary>
        public void OnTrackableStateChanged(
            TrackableBehaviour.Status previousStatus,
            TrackableBehaviour.Status newStatus)
        {
            if (newStatus == TrackableBehaviour.Status.DETECTED ||
                newStatus == TrackableBehaviour.Status.TRACKED ||
                newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
            {
                OnTrackingFound();
            }
            else
            {
                OnTrackingLost();
            }
        }

        #endregion // PUBLIC_METHODS

        #region PRIVATE_METHODS

        private void OnTrackingFound()
        {

            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // Enable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = true;
            }

            // Enable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = true;
            }

            text.text = mTrackableBehaviour.TrackableName + " erkannt";

            if (mTrackableBehaviour.TrackableName == "Unterwagen") {
                clickRight.Play ();
                text.text = "nimm ein Stück von diesem Sichtlagerkaste";
                //delay
                Invoke("", 10f); //-> it doesn't work
                SceneManager.LoadScene ("Scene3_Teil1_Bagger");

            } else {
                clickWrong.Play ();
            }
            Debug.Log ("Trackable " + mTrackableBehaviour.TrackableName + " found");

        }

        private void OnTrackingLost()
        {
            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // Disable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = false;
            }

            // Disable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = false;
            }

            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
            text.text = "Auf der Suche nach der Unterwagen Schrift";
        }

        #endregion // PRIVATE_METHODS

    }
}
</code>```

答:
Coroutines make this sort of delay-based logic very straight-forward:

```<code>void SomeFunction() {
    StartCoroutine(WaitThenDoTheThing());
}

IEnumerator WaitThenDoTheThing() {
    yield return new WaitForSeconds(NUM_SECONDS);
    TheThing();
}
</code>```

If you need to interrupt this for any reason, StartCoroutine will return a Coroutine object you may then hold on a reference to and kill with StopCoroutine(coroutineObject):

```<code>Coroutine routine;

void SomeFunction() {
    routine = StartCoroutine(WaitThenDoTheThing());
}

IEnumerator WaitThenDoTheThing() {
    yield return new WaitForSeconds(NUM_SECONDS);
    TheThing();
}

void KillCoroutine() {
    if (routine != null) {
        StopCoroutine(routine);
    }
}
</code>```

Body:
I'm working since 3 months with Unity engine and the last month I began to adding Vuforia capabilities to my Unity projects. Right now, I'm developing an application which comprises TextRecognition (Vuforia Prefab), see picture below. So, when the word "Unterwagen" is recognized, it should be load another scene that works perfectly. However, it should be a delay between this transition and I don't now how to do it. I would appreciate if someone can help me.

DefaultTrackableEvent.cs

    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.SceneManagement;

namespace Vuforia
{
    ///
    /// A custom handler that implements the ITrackableEventHandler interface.
    ///
    public class DefaultTrackableEventHandler1 : MonoBehaviour,
    ITrackableEventHandler
    {
        #region PRIVATE_MEMBER_VARIABLES

        private TrackableBehaviour mTrackableBehaviour;

        #endregion // PRIVATE_MEMBER_VARIABLES

        public GameObject _statusTxt;
        public AudioSource clickRight;
        public  AudioSource clickWrong;
        public Text text;

        #region UNTIY_MONOBEHAVIOUR_METHODS

        void Start()
        {

            mTrackableBehaviour = GetComponent<TrackableBehaviour>();
            if (mTrackableBehaviour)
            {
                mTrackableBehaviour.RegisterTrackableEventHandler(this);
            }

            text.text = "Auf der Suche nach der Unterwagen Schrift";
        }

        #endregion // UNTIY_MONOBEHAVIOUR_METHODS

        #region PUBLIC_METHODS

        ///
        /// Implementation of the ITrackableEventHandler function called when the
        /// tracking state changes.
        ///
        public void OnTrackableStateChanged(
            TrackableBehaviour.Status previousStatus,
            TrackableBehaviour.Status newStatus)
        {
            if (newStatus == TrackableBehaviour.Status.DETECTED ||
                newStatus == TrackableBehaviour.Status.TRACKED ||
                newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
            {
                OnTrackingFound();
            }
            else
            {
                OnTrackingLost();
            }
        }

        #endregion // PUBLIC_METHODS

        #region PRIVATE_METHODS

        private void OnTrackingFound()
        {

            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // Enable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = true;
            }

            // Enable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = true;
            }

            text.text = mTrackableBehaviour.TrackableName + " erkannt";

            if (mTrackableBehaviour.TrackableName == "Unterwagen") {
                clickRight.Play ();
                text.text = "nimm ein Stück von diesem Sichtlagerkaste";
                //delay
                Invoke("", 10f); //-> it doesn't work
                SceneManager.LoadScene ("Scene3_Teil1_Bagger");

            } else {
                clickWrong.Play ();
            }
            Debug.Log ("Trackable " + mTrackableBehaviour.TrackableName + " found");

        }

        private void OnTrackingLost()
        {
            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // Disable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = false;
            }

            // Disable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = false;
            }

            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
            text.text = "Auf der Suche nach der Unterwagen Schrift";
        }

        #endregion // PRIVATE_METHODS

    }
}

Body:
Coroutines make this sort of delay-based logic very straight-forward:

void SomeFunction() {
    StartCoroutine(WaitThenDoTheThing());
}

IEnumerator WaitThenDoTheThing() {
    yield return new WaitForSeconds(NUM_SECONDS);
    TheThing();
}

If you need to interrupt this for any reason, StartCoroutine will return a Coroutine object you may then hold on a reference to and kill with StopCoroutine(coroutineObject):

Coroutine routine;

void SomeFunction() {
    routine = StartCoroutine(WaitThenDoTheThing());
}

IEnumerator WaitThenDoTheThing() {
    yield return new WaitForSeconds(NUM_SECONDS);
    TheThing();
}

void KillCoroutine() {
    if (routine != null) {
        StopCoroutine(routine);
    }
}


问:
Why am I getting 'missing comma'?
I am completely new to SQL, and for a project for my intro level class.

I am getting a "missing comma" error for all of my INSERT statements when my numbers are in single quotes, and a "missing expression" error when they are not in quotes. I can not figure out where I am going wrong. Below is just one of my tables and an INSERT statement for that table, but this issue extends to all of my INSERT statements.

```<code>CREATE TABLE Cast(
Cast_ID NUMBER(7) NOT NULL PRIMARY KEY,
Cast_Member_Name VARCHAR2(64),
Oscars NUMBER(2)
);
COMMIT;

INSERT INTO Cast VALUES (17,’Tom Cruise’,0)
</code>```

Below is the error I receive when entering the above INSERT:

```<code>INSERT INTO Cast VALUES (17,.Tom Cruise.,0);
INSERT INTO Cast VALUES (17,.Tom Cruise.,0)

ERROR at line 1:
ORA-00936: missing expression
</code>```

答:
It looks like you created your SQL in a word processing program. These programs tend to use odd characters instead of "proper" apostrophes and double quote characters. The characters surrounding your string literals are not apostrophes; you'll need to fix them, as shown below:

```<code>INSERT INTO Cast VALUES (17,'Tom Cruise',0)
</code>```

Best of luck.

Title: Why am I getting 'missing comma'?

Body:
I am completely new to SQL, and for a project for my intro level class.

I am getting a "missing comma" error for all of my INSERT statements when my numbers are in single quotes, and a "missing expression" error when they are not in quotes. I can not figure out where I am going wrong. Below is just one of my tables and an INSERT statement for that table, but this issue extends to all of my INSERT statements.

CREATE TABLE Cast(
Cast_ID NUMBER(7) NOT NULL PRIMARY KEY,
Cast_Member_Name VARCHAR2(64),
Oscars NUMBER(2)
);
COMMIT;

INSERT INTO Cast VALUES (17,’Tom Cruise’,0)

Below is the error I receive when entering the above INSERT:

INSERT INTO Cast VALUES (17,.Tom Cruise.,0);
INSERT INTO Cast VALUES (17,.Tom Cruise.,0)

ERROR at line 1:
ORA-00936: missing expression

Body:
It looks like you created your SQL in a word processing program. These programs tend to use odd characters instead of "proper" apostrophes and double quote characters. The characters surrounding your string literals are not apostrophes; you'll need to fix them, as shown below:

INSERT INTO Cast VALUES (17,'Tom Cruise',0)

Best of luck.


问:
Time complexity for comparing two numbers
I'm trying to establish the time complexity of an algorithm that involves comparison of numbers.

Say I have two numbers A and B, where both numbers have N number of digits individually. Assume it also holds that A<=K and B<=K.

Now I want to compare if A<=B (if A is less than or equal to B).

I suspect that the time complexity is either O(N) or O(K).

What is the correct time complexity?

答:
I don't know why people are suggesting you to look at numerous answers. In your case, the complexity is clearly O(N).

First you compare the signs - if they differ, you know the higher number and the lower number.

If the signs are same, you start from the most significant digit of both numbers and if at any place the digit differs, you can figure out which number is bigger than the other.

In case the numbers are negative, the larger most significant digit will imply that the number is smaller.


问:
How to link to current page with different param in react router?
Let's say I have the following routes set up (just an example, actual routes aren't this messy):

```<code><Router>
  <Switch>
    <Route path="/app/fun/:userid/profile" component={Profile} exact/>
    <Route path="/photos/:userid" component={Photos} exact/>
    <Route path="/:userid/contact" component={Contact} exact/>
  </Switch>
</Router>
</code>```

From ANY of the pages above, how can I link to the SAME page, but with a different userid?

eg:

```<code>/**
 * Shared component that's rendered by Profile, Photos and Contact
 */
class SharedComponent extends React.Component {
  render() {
    const bobId = 423423432;

    return (
      <div>
        <Link to={/* what to put here? */}>
          Redirect to the same page but with Bob's userid
        </Link>
      </div>
    );
  }
}

export default withRouter(SharedComponent);
</code>```

Note: using react router v4

答:
Actually, I found a way to do this. Not sure if it's the best way, but it works:

```<code>/**
 * Shared component that's rendered by Profile, Photos and Contact
 */
class SharedComponent extends React.Component {
  render() {
    const { location, match } = this.props;
    const bobId = 423423432;
    const bobUrl = location.pathname.replace(match.params.userid, bobId);

    return (
      <div>
        <Link to={bobUrl}>
          Redirect to the same page but with Bob's userid
        </Link>
      </div>
    );
  }
}

export default withRouter(SharedComponent);
</code>```

Essentially, I'm taking the current url (location.pathname) and replacing the current userid (match.params.userid) with the new id (bobId)

Body:
Let's say I have the following routes set up (just an example, actual routes aren't this messy):

<Router>
  <Switch>
    <Route path="/app/fun/:userid/profile" component={Profile} exact/>
    <Route path="/photos/:userid" component={Photos} exact/>
    <Route path="/:userid/contact" component={Contact} exact/>
  </Switch>
</Router>

From ANY of the pages above, how can I link to the SAME page, but with a different userid?

eg:

/**
 * Shared component that's rendered by Profile, Photos and Contact
 */
class SharedComponent extends React.Component {
  render() {
    const bobId = 423423432;

    return (

        <Link to={/* what to put here? */}>
          Redirect to the same page but with Bob's userid
        </Link>

    );
  }
}

export default withRouter(SharedComponent);

Note: using react router v4

Body:
Actually, I found a way to do this. Not sure if it's the best way, but it works:

/**
 * Shared component that's rendered by Profile, Photos and Contact
 */
class SharedComponent extends React.Component {
  render() {
    const { location, match } = this.props;
    const bobId = 423423432;
    const bobUrl = location.pathname.replace(match.params.userid, bobId);

    return (
      <div>
        <Link to={bobUrl}>
          Redirect to the same page but with Bob's userid
        </Link>
      </div>
    );
  }
}

export default withRouter(SharedComponent);

Essentially, I'm taking the current url (location.pathname) and replacing the current userid (match.params.userid) with the new id (bobId)


问:
How is this JavaScript code working without invoking the functions?
This is the codepen of the code https://codepen.io/p5js/pen/wreBKy . Shouldn't the canvas be created only if I call the function with setup(); ?

HTML

```<code><html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/addons/p5.dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <script src="sketch.js"></script>
  </body>
</html>
</code>```

CSS

```<code>html, body {
  margin: 0;
  padding: 0;
}
</code>```

JavaScript

```<code>function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);

}
</code>```

答:
Not quite, the setup and draw functions are special, in such a way that p5 library calls them automatically if it sees them declared by you in the global namespace.

That is, you don't have to call them manually, the library calls them at the most appropriate time for you.

You can read more about that on the Get Started section of the p5 docs.

Body:
This is the codepen of the code https://codepen.io/p5js/pen/wreBKy . Shouldn't the canvas be created only if I call the function with setup(); ?

HTML

    <link rel="stylesheet" type="text/css" href="style.css">

CSS

html, body {
  margin: 0;
  padding: 0;
}

JavaScript

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);

}


问:
In perl, when assigning a subroutine's return value to a variable, is the data duplicated in memory?
```<code>sub foo {
    my @return_value = (1, 2);
}
my @receiver = foo();
</code>```

Is this assigning like any other assigning in perl? the array is duplicated in memory? I doubt this cause of that since the array held by the subroutine is disposable, a duplication is totally redundant. it makes sense to just 'link' the array to @receiver for optimization reason.

by the way, I noticed a similar question Perl: function returns reference or copy? but didn't get what I want.

and I'm talking about Perl5

ps. any books or materials on such sort of topics about perl?

答:
The subroutine returns the result of the last operation if you don't specify an explicit return.

@return_value is created separately from @receiver and the values are copied and the memory used by @return_value is released when it goes out of scope at subroutine exit.

So yes - the memory used is duplicated.

If you desperately want to avoid this, you can create an anonymous array once, and 'pass' a reference to it around:

```<code>#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;

sub foo {
    my $anon_array_ref = [ 1, 2 ];
    return $anon_array_ref;
}

my $results_from_foo = foo();

print Dumper $results_from_foo;
</code>```

This will usually be premature optimisation though, unless you know you're dealing with really big data structures.

Note - you should probably include an explicit return; in your sub after the assignment, as it's good practice to make clear what you're doing.

Body:
sub foo {
    my @return_value = (1, 2);
}
my @receiver = foo();

Is this assigning like any other assigning in perl? the array is duplicated in memory? I doubt this cause of that since the array held by the subroutine is disposable, a duplication is totally redundant. it makes sense to just 'link' the array to @receiver for optimization reason.

by the way, I noticed a similar question Perl: function returns reference or copy? but didn't get what I want.

and I'm talking about Perl5

ps. any books or materials on such sort of topics about perl?

Body:
The subroutine returns the result of the last operation if you don't specify an explicit return.

@return_value is created separately from @receiver and the values are copied and the memory used by @return_value is released when it goes out of scope at subroutine exit.

So yes - the memory used is duplicated.

If you desperately want to avoid this, you can create an anonymous array once, and 'pass' a reference to it around:

#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;

sub foo {
    my $anon_array_ref = [ 1, 2 ];
    return $anon_array_ref;
}

my $results_from_foo = foo();

print Dumper $results_from_foo;

This will usually be premature optimisation though, unless you know you're dealing with really big data structures.

Note - you should probably include an explicit return; in your sub after the assignment, as it's good practice to make clear what you're doing.


问:
install python package from github using requirements.txt
Whats the successful way to import packages from github repo?

Here is what I tried
Tried Installing a python package- corepkg,  which is available in git repository - git.example.com/corepkg.git

In another Project- Proj2, to import logic from above corepkg package, Kept an entry in requirements.txt and ran the following pip command.

pip install -r requirements.txt

Here are my Entries in requirement.txt for Proj2

```<code>...
PyYAML==3.12
requests==2.18.4
urllib3==1.22
git+https://git.example.com/corepkg.git@develop
</code>```

But it did not create any src folder or .dist-info folder in virtual environment site-packages?
It just created corepkg-1-py3.6.egg_info file but not files required to import.

Whats the step I am missing here to import it successfully from git?

答:
Try

```<code>git+https://git.example.com/corepkg.git@develop#egg=corepkg
</code>```

See https://pip.readthedocs.io/en/stable/reference/pip_install/#vcs-support

The problem also could be in the very corepkg.git repo so it's hard to say something without looking at the repo.

Body:
Whats the successful way to import packages from github repo?

Here is what I tried
Tried Installing a python package- corepkg,  which is available in git repository - git.example.com/corepkg.git

In another Project- Proj2, to import logic from above corepkg package, Kept an entry in requirements.txt and ran the following pip command.

pip install -r requirements.txt

Here are my Entries in requirement.txt for Proj2

...
PyYAML==3.12
requests==2.18.4
urllib3==1.22
git+https://git.example.com/corepkg.git@develop

But it did not create any src folder or .dist-info folder in virtual environment site-packages?
It just created corepkg-1-py3.6.egg_info file but not files required to import.

Whats the step I am missing here to import it successfully from git?

Body:
Try

git+https://git.example.com/corepkg.git@develop#egg=corepkg

See https://pip.readthedocs.io/en/stable/reference/pip_install/#vcs-support

The problem also could be in the very corepkg.git repo so it's hard to say something without looking at the repo.


问:
Can you bind 'this' in an arrow function?
I've been experimenting with ES6 for a while now, and I've just come to a slight problem.

I really like using arrow functions, and whenever I can, I use them.

However, it would appear that you can't bind them!

Here is the function:

```<code>var f = () => console.log(this);
</code>```

Here is the object I want to bind the function to:

```<code>var o = {'a': 42};
</code>```

And here is how I would bind f to o:

```<code>var fBound = f.bind(o);
</code>```

And then I can just call fBound:

```<code>fBound();
</code>```

Which will output this (the o object):

```<code>{'a': 42}
</code>```

Cool! Lovely! Except that it doesn't work. Instead of outputting the o object, it outputs the window object.

So I'd like to know: can you bind arrow functions? (And if so, how?)

I've tested the code above in Google Chrome 48 and Firefox 43, and the result is the same.

答:
To be complete, you can re-bind arrow functions, you just can't change the meaning of this.

bind still has value for function arguments:

```<code>((a, b, c) => {
  console.info(a, b, c) // 1, 2, 3
}).bind(undefined, 1, 2, 3)()
</code>```

Try it here:
http://jsbin.com/motihanopi/edit?js,console

Body:
I've been experimenting with ES6 for a while now, and I've just come to a slight problem.

I really like using arrow functions, and whenever I can, I use them.

However, it would appear that you can't bind them!

Here is the function:

var f = () => console.log(this);

Here is the object I want to bind the function to:

var o = {'a': 42};

And here is how I would bind f to o:

var fBound = f.bind(o);

And then I can just call fBound:

fBound();

Which will output this (the o object):

{'a': 42}

Cool! Lovely! Except that it doesn't work. Instead of outputting the o object, it outputs the window object.

So I'd like to know: can you bind arrow functions? (And if so, how?)

I've tested the code above in Google Chrome 48 and Firefox 43, and the result is the same.

Body:
To be complete, you can re-bind arrow functions, you just can't change the meaning of this.

bind still has value for function arguments:

((a, b, c) => {
  console.info(a, b, c) // 1, 2, 3
}).bind(undefined, 1, 2, 3)()

Try it here:
http://jsbin.com/motihanopi/edit?js,console


问:
How to pass arguments from wrapper shell script to Java application?
I want to run Java programs I am creating at on the command line (linux and mac).  I don't want to type "java" and arguments all the time, so I am thinking about creating wrapper scripts.  What's the best way to do this so that they work everywhere?  I want to be able to pass arguments, too.  I was thinking of using "shift" to do this (removing first argument).

Is there a better way to do this without using scripts at all?  Perhaps make an executable that doesn't require invocation through the "java" command?

答:
You can create a shell script that accepts arguments. In your shell script, it will look something like this:-

```<code>java YourApp $1 $2
</code>```

In this case, YourApp accepts two arguments. If your shell script is called app.sh, you can execute it like this:-

```<code>./app.sh FirstArgument SecondArgument
</code>```

Body:
You can create a shell script that accepts arguments. In your shell script, it will look something like this:-

java YourApp $1 $2

In this case, YourApp accepts two arguments. If your shell script is called app.sh, you can execute it like this:-

./app.sh FirstArgument SecondArgument

ContentLicense: CC BY-SA 2.5


问:
Can i deploy my php project with gitlab ci to remote host WITHOUT Docker images?
We have PHP project on gitlab. I can deploy it using Jenkins + Phping to remote host, but Jenkins run slow often. I see many examples with Gitlab-ci and Docker images, but  I don't want to use Docker images. I just want to git clone this project to remote host after some jobs triggers and to make some jobs after this on remote host. I saw gitlab-ci runners ssh and shell, maybe it makes using one of this runners?

Can i deploy my PHP project with gitlab ci to remote host without Docker images? Will be it correct?

答:
I have done it few weeks ago.
In that case I was using gitlab-ci with the shell runner, it worked fine for me. I had some problems with ssh keys, but I fixed it reading a little:

http://www.linuxproblem.org/art_9.html

and

https://apple.stackexchange.com/questions/48502/how-can-i-permanently-add-my-ssh-private-key-to-keychain-so-it-is-automatically

So, yes you can deploy it this way and it's fine to do it.

I'm adding a .gitlab-ci.yml that I used to deploy a jar application.

```<code>image: JAVA:latest

before_script:
  - /home/leandro/netbeans-8.2/java/maven/bin/mvn clean install

after_script:

stages:
  - build_deploy_dev
  - build_deploy_production

build_&_deploy_dev:
  stage: build_deploy_dev
  except:
   - master
  script:
   - cd target
   - scp EnviaEmail-1.0-SNAPSHOT-jar-with-dependencies.jar root@192.168.0.147:/home/leandro/Desktop
   - ssh root@192.168.0.147 "kill $(ps -ef | grep EnviaEmail | grep -v grep | awk '{print $2}') < /dev/null > /home/leandro/Desktop/KillEnviaEmail.log 2>&1 &"
   - ssh root@192.168.0.147 "java -jar /home/leandro/Desktop/EnviaEmail-1.0-SNAPSHOT-jar-with-dependencies.jar -Xmx256m < /dev/null > /home/leandro/Desktop/EnviaEmail.log 2>&1 &"
</code>```

Hope it helps

Body:
I have done it few weeks ago.
In that case I was using gitlab-ci with the shell runner, it worked fine for me. I had some problems with ssh keys, but I fixed it reading a little:

http://www.linuxproblem.org/art_9.html

and

https://apple.stackexchange.com/questions/48502/how-can-i-permanently-add-my-ssh-private-key-to-keychain-so-it-is-automatically

So, yes you can deploy it this way and it's fine to do it.

I'm adding a .gitlab-ci.yml that I used to deploy a jar application.

image: JAVA:latest

before_script:
  - /home/leandro/netbeans-8.2/java/maven/bin/mvn clean install

after_script:

stages:
  - build_deploy_dev
  - build_deploy_production

build_&_deploy_dev:
  stage: build_deploy_dev
  except:
   - master
  script:
   - cd target
   - scp EnviaEmail-1.0-SNAPSHOT-jar-with-dependencies.jar root@192.168.0.147:/home/leandro/Desktop
   - ssh root@192.168.0.147 "kill $(ps -ef | grep EnviaEmail | grep -v grep | awk '{print $2}') < /dev/null > /home/leandro/Desktop/KillEnviaEmail.log 2>&1 &"
   - ssh root@192.168.0.147 "java -jar /home/leandro/Desktop/EnviaEmail-1.0-SNAPSHOT-jar-with-dependencies.jar -Xmx256m < /dev/null > /home/leandro/Desktop/EnviaEmail.log 2>&1 &"

Hope it helps


问:
const string vs. #define
i need to share some strings in my c++ program. should i use #define or const string? thanks

mystring1.h

```<code>#define str1 "str1"
#define str2 "str2"
</code>```

Or

mystring2.h

```<code>extern const string str1;
extern const string str2;
</code>```

mystring.cpp

```<code>const string str1 = "str1";
const string str2 = "str2";
</code>```

答:
If it is C++ instead of C, you should really use some variable instead of a preprocessor macro. The former is clearer than the latter. Furthermore, if you use C++17, you can use inline variables:

```<code>inline const std::string str = "foobar";
</code>```

or

```<code>// constexpr is implicitly inline
constexpr char str0[] = "foobar";
constexpr const char* str1 = "foobar";
constexpr std::string_view str2 = "foobar";
</code>```

This is also clearer than using extern and can be used in header-only APIs as well.

Title: const string vs. #define

Body:
i need to share some strings in my c++ program. should i use #define or const string? thanks

mystring1.h

#define str1 "str1"
#define str2 "str2"

Or

mystring2.h

extern const string str1;
extern const string str2;

mystring.cpp

const string str1 = "str1";
const string str2 = "str2";

Body:
If it is C++ instead of C, you should really use some variable instead of a preprocessor macro. The former is clearer than the latter. Furthermore, if you use C++17, you can use inline variables:

inline const std::string str = "foobar";

or

// constexpr is implicitly inline
constexpr char str0[] = "foobar";
constexpr const char* str1 = "foobar";
constexpr std::string_view str2 = "foobar";

This is also clearer than using extern and can be used in header-only APIs as well.


问:
Having trouble in creating new row/ cell with custom labels
Using Swift, My custom cell has 4 labels which I would like to edit when adding the new row/cell to the tableview.

On top of my app in the bar I have an add button which is supposed to add the new cell/row to the table view but only the first one works and when I add a second cell/row it changes and becomes smaller.

I know the code is wrong obviously but I can't seem to fix it as its using an array called objects but I can't seem to be able to add multiple strings to the object to be used in the table view.

I'm using the standard Master Detail template for the project but in changing the code to be custom to my liking I ran into these problems.

```<code>override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return objects.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell

    //let object = objects[indexPath.row] as! String // NSDate
    //cell.textLabel!.text = object.description

    cell.firstLabel.text = "name"
    cell.secondLabel.text = "bought"
    cell.thirdLabel.text = "18"
    cell.fourthLabel.text = "30"

    return cell
}

override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        objects.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .fade)
    } else if editingStyle == .insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}

@objc
func insertNewObject(_ sender: Any) {

    // Adding cell with new added info

    // can not be an array of strings, has to be an array of an array of strings, doesn't it?
    // "tester" is was there from the project template
    let test: String = "tester"
    objects.insert(test, at: 0) // NSDate()

    let indexPath = IndexPath(row: 0, section: 0)
    tableView.insertRows(at: [indexPath], with: .automatic)
}

// MARK: - Segues

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetail" {
        if let indexPath = tableView.indexPathForSelectedRow {
            let object = objects[indexPath.row] as! NSDate
            let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
            controller.detailItem = object
            controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
            controller.navigationItem.leftItemsSupplementBackButton = true
        }
    }
}

@IBOutlet var myTableView: UITableView!
var detailViewController: DetailViewController? = nil
var objects = [Any]()

override func viewDidLoad() {
    super.viewDidLoad()

    // Custom Cell
    self.myTableView.dataSource = self
    self.myTableView.delegate = self

    // Do any additional setup after loading the view, typically from a nib.
    navigationItem.leftBarButtonItem = editButtonItem

    let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
    navigationItem.rightBarButtonItem = addButton
    if let split = splitViewController {
        let controllers = split.viewControllers
        detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
    }
}
</code>```

答:
I think you should try to implement method  tableView(_:heightForRowAt:) -> CGFloat

Please try to return 88.0f and see the difference

Body:
Using Swift, My custom cell has 4 labels which I would like to edit when adding the new row/cell to the tableview.

On top of my app in the bar I have an add button which is supposed to add the new cell/row to the table view but only the first one works and when I add a second cell/row it changes and becomes smaller.

I know the code is wrong obviously but I can't seem to fix it as its using an array called objects but I can't seem to be able to add multiple strings to the object to be used in the table view.

I'm using the standard Master Detail template for the project but in changing the code to be custom to my liking I ran into these problems.

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return objects.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell

    //let object = objects[indexPath.row] as! String // NSDate
    //cell.textLabel!.text = object.description

    cell.firstLabel.text = "name"
    cell.secondLabel.text = "bought"
    cell.thirdLabel.text = "18"
    cell.fourthLabel.text = "30"

    return cell
}

override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        objects.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .fade)
    } else if editingStyle == .insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}

@objc
func insertNewObject(_ sender: Any) {

    // Adding cell with new added info

    // can not be an array of strings, has to be an array of an array of strings, doesn't it?
    // "tester" is was there from the project template
    let test: String = "tester"
    objects.insert(test, at: 0) // NSDate()

    let indexPath = IndexPath(row: 0, section: 0)
    tableView.insertRows(at: [indexPath], with: .automatic)
}

// MARK: - Segues

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetail" {
        if let indexPath = tableView.indexPathForSelectedRow {
            let object = objects[indexPath.row] as! NSDate
            let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
            controller.detailItem = object
            controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
            controller.navigationItem.leftItemsSupplementBackButton = true
        }
    }
}

@IBOutlet var myTableView: UITableView!
var detailViewController: DetailViewController? = nil
var objects = [Any]()

override func viewDidLoad() {
    super.viewDidLoad()

    // Custom Cell
    self.myTableView.dataSource = self
    self.myTableView.delegate = self

    // Do any additional setup after loading the view, typically from a nib.
    navigationItem.leftBarButtonItem = editButtonItem

    let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
    navigationItem.rightBarButtonItem = addButton
    if let split = splitViewController {
        let controllers = split.viewControllers
        detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
    }
}


问:
multiple pies with scatterpie or ggforce
I am trying to plot multiple piecharts on top of an image. I want to use custom_annotation to plot the rastered image. But right now I can't even get the multiple piecharts.

Ultimately I want 6 pies plotting in differnet spots over top of an image. imX and imY give the coordinates of where the pies should be on the image.

```<code>head(wholebody_cutLH_wide_t[c(1,2,102,103,104)])
Acidobacteriaceae Actinomycetaceae  imX imY radius
1      0.000000e+00     7.665687e-05 2.00 5.5    0.5
2      0.000000e+00     4.580237e-04 1.50 1.0    0.5
3      0.000000e+00     4.112573e-04 1.75 2.0    0.5
4      6.431473e-04     3.856008e-02 0.30 1.0    0.5
5      0.000000e+00     3.013013e-04 1.50 4.8    0.5
6      3.399756e-05     1.372986e-02 1.50 5.2    0.5
</code>```

Now here is my attempt with scatterpie:

```<code>ggplot(wholebody_cutLH_wide_t) +
 #  annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
 geom_scatterpie(aes(x=imX, y=imY,r=radius),
            data=wholebody_cutLH_wide_t, cols=NA,color=sample(allcolors,101)) +
 scale_color_manual(values=sample(allcolors,101)) +
 scale_x_continuous(expand=c(0,0), lim=c(0,3)) +
 scale_y_continuous(expand=c(0,0), lim=c(0,6)) +
 theme(legend.position="none",
    panel.background = element_rect(fill = "transparent") # bg of the panel
    , plot.background = element_rect(fill = "transparent") # bg of the plot
    , panel.grid.major = element_blank() # get rid of major grid
    , panel.grid.minor = element_blank(), # get rid of minor grid
    line = element_blank(),
    text = element_blank(),
    title = element_blank()
  )
</code>```

Now my error is:

```<code>Error: Only strings can be converted to symbols
</code>```

Here is my attempt with dplyr and ggforce:

```<code>dat_pies<-left_join(wholebody_cutLH,
                wholebody_cutLH %>%
                  group_by(tax_rank) %>%
                  summarize(Cnt_total = sum(count_norm))) %>%
group_by(tax_rank) %>%
mutate(end_angle = 2*pi*cumsum(count_norm)/Cnt_total,      # ending angle for   each pie slice
     start_angle = lag(end_angle, default = 0),   # starting angle for each pie slice
     mid_angle = 0.5*(start_angle + end_angle))

ggplot(dat_pies) +
geom_arc_bar(aes(x0 = imX, y0 = imY, r0 = 0, r = rpie,
               start = start_angle, end = end_angle, fill = Volume)) +
geom_text(aes(x = rlabel*sin(mid_angle), y = rlabel*cos(mid_angle), label = Cnt),
        hjust = 0.5, vjust = 0.5) +
coord_fixed() +
scale_x_continuous(expand=c(0,0), lim=c(0,3)) +
scale_y_continuous(expand=c(0,0), lim=c(0,6)) +
</code>```

Here my error is :

```<code>Error in ggplot(dat_pies) + geom_arc_bar(aes(x0 = imX, y0 = imY, r0 = 0,  :
could not find function "+<-"
</code>```

Any help with either of these methods would be great.
thanks

答:
In your first attempt you should use:

```<code>ggplot(wholebody_cutLH_wide_t) +
  geom_scatterpie(aes(x=imX, y=imY,r=radius),
     data=wholebody_cutLH_wide_t,
     cols=colnames(wholebody_cutLH_wide_t)[1:2],
     color=NA, alpha=.8)
</code>```

Body:
I am trying to plot multiple piecharts on top of an image. I want to use custom_annotation to plot the rastered image. But right now I can't even get the multiple piecharts.

Ultimately I want 6 pies plotting in differnet spots over top of an image. imX and imY give the coordinates of where the pies should be on the image.

head(wholebody_cutLH_wide_t[c(1,2,102,103,104)])
Acidobacteriaceae Actinomycetaceae  imX imY radius
1      0.000000e+00     7.665687e-05 2.00 5.5    0.5
2      0.000000e+00     4.580237e-04 1.50 1.0    0.5
3      0.000000e+00     4.112573e-04 1.75 2.0    0.5
4      6.431473e-04     3.856008e-02 0.30 1.0    0.5
5      0.000000e+00     3.013013e-04 1.50 4.8    0.5
6      3.399756e-05     1.372986e-02 1.50 5.2    0.5

Now here is my attempt with scatterpie:

ggplot(wholebody_cutLH_wide_t) +
 #  annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
 geom_scatterpie(aes(x=imX, y=imY,r=radius),
            data=wholebody_cutLH_wide_t, cols=NA,color=sample(allcolors,101)) +
 scale_color_manual(values=sample(allcolors,101)) +
 scale_x_continuous(expand=c(0,0), lim=c(0,3)) +
 scale_y_continuous(expand=c(0,0), lim=c(0,6)) +
 theme(legend.position="none",
    panel.background = element_rect(fill = "transparent") # bg of the panel
    , plot.background = element_rect(fill = "transparent") # bg of the plot
    , panel.grid.major = element_blank() # get rid of major grid
    , panel.grid.minor = element_blank(), # get rid of minor grid
    line = element_blank(),
    text = element_blank(),
    title = element_blank()
  )

Now my error is:

Error: Only strings can be converted to symbols

Here is my attempt with dplyr and ggforce:

dat_pies<-left_join(wholebody_cutLH,
                wholebody_cutLH %>%
                  group_by(tax_rank) %>%
                  summarize(Cnt_total = sum(count_norm))) %>%
group_by(tax_rank) %>%
mutate(end_angle = 2*pi*cumsum(count_norm)/Cnt_total,      # ending angle for   each pie slice
     start_angle = lag(end_angle, default = 0),   # starting angle for each pie slice
     mid_angle = 0.5*(start_angle + end_angle))

ggplot(dat_pies) +
geom_arc_bar(aes(x0 = imX, y0 = imY, r0 = 0, r = rpie,
               start = start_angle, end = end_angle, fill = Volume)) +
geom_text(aes(x = rlabel*sin(mid_angle), y = rlabel*cos(mid_angle), label = Cnt),
        hjust = 0.5, vjust = 0.5) +
coord_fixed() +
scale_x_continuous(expand=c(0,0), lim=c(0,3)) +
scale_y_continuous(expand=c(0,0), lim=c(0,6)) +

Here my error is :

Error in ggplot(dat_pies) + geom_arc_bar(aes(x0 = imX, y0 = imY, r0 = 0,  :
could not find function "+<-"

Any help with either of these methods would be great.
thanks

Body:
In your first attempt you should use:

ggplot(wholebody_cutLH_wide_t) +
  geom_scatterpie(aes(x=imX, y=imY,r=radius),
     data=wholebody_cutLH_wide_t,
     cols=colnames(wholebody_cutLH_wide_t)[1:2],
     color=NA, alpha=.8)


问:
Joining 2 tables with limited joining conditions
I am quite new to SQL and I am trying to join two tables,

Table A:

```<code>ID  Amount    Bank
123  50        Barclays
123  50        tesco
123  50        HSBC
123  100       LLyods
123  200       MBNA
</code>```

Table B:

```<code>ID  Amount    Bank
123  50        aa
123  50        bb
123  50        cc
123  100       dd
123  200       ee
</code>```

Note that: in table B the bank name is the same as table A but it is written in a different format, so I can't join on this.

the script i am running is:

```<code>Select A.*, B.*
FROM TableA  A
Left Join TableB B
on A.ID = B.ID AND A.AMOUNT = B.AMOUNT
;
</code>```

The result i get is,

```<code>ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  Barclays    123 50      bb
123 50  Barclays    123 50      cc
123 50  tesco       123 50      aa
123 50  tesco       123 50      bb
123 50  tesco       123 50      cc
123 50  HSBC        123 50      aa
123 50  HSBC        123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee
</code>```

what i want to get is,

```<code>ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  tesco       123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee
</code>```

I get the issue is that it joining each row of table A to the rows of table B which meet the join conditions; unfortunately the table B has no other unique values that I can use as a join condition;

Can the community please see if you can think of something, I would very much appreciate it. Thank you :)

答:
Is it possible for you to create a third table, matching the Table A Bank values to their corresponding Table B Bank values? Because without some sort of linking table specifying the relationship, the SQL server has no way of knowing that 'Barclays' = 'aa', 'tesco' = 'bb', etc. There has to be some sort of unique relationship, and you don't have that in the two tables provided.

LinkTable:

```<code>Code    Bank
aa       Barclays
bb   tesco
cc   HSBC
dd   LLyods
e    MBNA
</code>```

You can then do:

```<code>Select A.*, B.*
FROM TableA  A
  JOIN LinkTable LB ON (A.Bank = LB.Bank)
  JOIN TableB B ON (LB.ID = B.Bank);
</code>```

Body:
I am quite new to SQL and I am trying to join two tables,

Table A:

ID  Amount    Bank
123  50        Barclays
123  50        tesco
123  50        HSBC
123  100       LLyods
123  200       MBNA

Table B:

ID  Amount    Bank
123  50        aa
123  50        bb
123  50        cc
123  100       dd
123  200       ee

Note that: in table B the bank name is the same as table A but it is written in a different format, so I can't join on this.

the script i am running is:

Select A.*, B.*
FROM TableA  A
Left Join TableB B
on A.ID = B.ID AND A.AMOUNT = B.AMOUNT
;

The result i get is,

ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  Barclays    123 50      bb
123 50  Barclays    123 50      cc
123 50  tesco       123 50      aa
123 50  tesco       123 50      bb
123 50  tesco       123 50      cc
123 50  HSBC        123 50      aa
123 50  HSBC        123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee

what i want to get is,

ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  tesco       123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee

I get the issue is that it joining each row of table A to the rows of table B which meet the join conditions; unfortunately the table B has no other unique values that I can use as a join condition;

Can the community please see if you can think of something, I would very much appreciate it. Thank you :)

Body:
Is it possible for you to create a third table, matching the Table A Bank values to their corresponding Table B Bank values? Because without some sort of linking table specifying the relationship, the SQL server has no way of knowing that 'Barclays' = 'aa', 'tesco' = 'bb', etc. There has to be some sort of unique relationship, and you don't have that in the two tables provided.

LinkTable:

Code    Bank
aa       Barclays
bb   tesco
cc   HSBC
dd   LLyods
e    MBNA

You can then do:

Select A.*, B.*
FROM TableA  A
  JOIN LinkTable LB ON (A.Bank = LB.Bank)
  JOIN TableB B ON (LB.ID = B.Bank);


问:
How to monitor desktop environment mouse event in gtk programming
In GTK programming, how to monitor desktop environment mouse event while the GTK application is not active, i.e, the mouse is focus on other GTK application?</p>

答:
Finally, I found a library keybinder which is what I want!

The homepage(http://kaizer.se/wiki/keybinder/) of that library introduces that keybinder is a library for registering global keyboard shortcuts. Keybinder works with GTK-based applications using the X Window System.


问:
ExtractXML Oracle Query Returns Null
I have the below data in a column called "attributes" of a table "data" on Oracle 12c database:

```<code><Attributes>
  <Map>
    <entry key="accountFlags">
      <value>
        <List>
          <String>Normal User Account</String>
        </List>
      </value>
    </entry>
    <entry key="cn" value="paul.john"/>
    <entry key="department" value="IT"/>
    <entry key="description" value="New account. Automatically created"/>
    <entry key="displayName" value="John, Paul"/>
    <entry key="distinguishedName" value="CN=paul.john,OU=Users,DC=test,DC=com"/>
    <entry key="givenName" value="Paul"/>
    <entry key="homeMDB" value="CN=Test,CN=Databases,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=test,DC=com"/>
    <entry key="l" value="London"/>
    <entry key="mail" value="paul.john@test.com"/>
    <entry key="mailNickname" value="PaulJ"/>
    <entry key="manager" value="CN=brock.lesnar,OU=Users,DC=test,DC=com"/>
    <entry key="memberOf">
      <value>
        <List>
          <String>CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test2,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test3,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com</String>
        </List>
      </value>
    </entry>
  </Map>
</Attributes>
</code>```

I wish to extract the value of "memberOf" from this column like this:

```<code>MEMBER_OF
---------
CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test2,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test3,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com
</code>```

I have tried this with the below query which is returning null:

```<code>SELECT EXTRACTVALUE(xmltype(attributes), '/Attributes/Map/entry[@key="memberOf"]/value/List/@String')
FROM DATA;
</code>```

I have also tried the below query which also returns null

```<code>SELECT EXTRACTVALUE(xmltype(attributes), '/Attributes/Map/entry[@key="memberOf"]/value[1]/List/@String')
FROM DATA;
</code>```

Not sure if there is something else that needs to be passed in the query?

答:
Try this</p>

```<code>SELECT y.*
  FROM (SELECT *
          FROM XMLTABLE ('/Attributes/Map/entry[@key="memberOf"]/value/List'
                         PASSING (SELECT xmltype (attributes)
                                    FROM data)
                         COLUMNS strings XMLTYPE PATH 'String')) x,
       XMLTABLE ('/String'
                 PASSING x.strings
                 COLUMNS memberOf VARCHAR (300) PATH '.') y;
</code>```

Title: ExtractXML Oracle Query Returns Null

Body:
I have the below data in a column called "attributes" of a table "data" on Oracle 12c database:

<Attributes>
  <Map>
    <entry key="accountFlags">
      <value>
        <List>
          <String>Normal User Account</String>
        </List>
      </value>
    </entry>
    <entry key="cn" value="paul.john"/>
    <entry key="department" value="IT"/>
    <entry key="description" value="New account. Automatically created"/>
    <entry key="displayName" value="John, Paul"/>
    <entry key="distinguishedName" value="CN=paul.john,OU=Users,DC=test,DC=com"/>
    <entry key="givenName" value="Paul"/>
    <entry key="homeMDB" value="CN=Test,CN=Databases,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=test,DC=com"/>
    <entry key="l" value="London"/>
    <entry key="mail" value="paul.john@test.com"/>
    <entry key="mailNickname" value="PaulJ"/>
    <entry key="manager" value="CN=brock.lesnar,OU=Users,DC=test,DC=com"/>
    <entry key="memberOf">
      <value>
        <List>
          <String>CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test2,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test3,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com</String>
        </List>
      </value>
    </entry>
  </Map>
</Attributes>

I wish to extract the value of "memberOf" from this column like this:

MEMBER_OF
---------
CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test2,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test3,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com

I have tried this with the below query which is returning null:

SELECT EXTRACTVALUE(xmltype(attributes), '/Attributes/Map/entry[@key="memberOf"]/value/List/@String')
FROM DATA;

I have also tried the below query which also returns null

SELECT EXTRACTVALUE(xmltype(attributes), '/Attributes/Map/entry[@key="memberOf"]/value[1]/List/@String')
FROM DATA;

Not sure if there is something else that needs to be passed in the query?

Body:
Try this

SELECT y.*
  FROM (SELECT *
          FROM XMLTABLE ('/Attributes/Map/entry[@key="memberOf"]/value/List'
                         PASSING (SELECT xmltype (attributes)
                                    FROM data)
                         COLUMNS strings XMLTYPE PATH 'String')) x,
       XMLTABLE ('/String'
                 PASSING x.strings
                 COLUMNS memberOf VARCHAR (300) PATH '.') y;


问:
Color keying video with GPUImage on a SCNPlane in ARKit
I am trying to play a video, showing transparency in an ARSCNView. A SCNPlane is used as a projection space for the video and I am trying to color key this video with GPUImage.

I followed this example here. Unfortunately, I have not found a way to project that video back on my videoSpriteKitNode. Because the filter is rendered in a GPUImageView, and the SKVideoNode takes a AVPlayer.

I am not sure if it is possible at all, what I am trying to do, so if anyone could share their insight I'd be very thankful!

```<code>import UIKit
import ARKit
import GPUImage

class ARTransVC: UIViewController{

@IBOutlet weak var sceneView: ARSCNView!
let configuration = ARWorldTrackingConfiguration()
var movie: GPUImageMovie!
var filter: GPUImageChromaKeyBlendFilter!
var sourcePicture: GPUImagePicture!
var player = AVPlayer()
var gpuImageView: GPUImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints]
    self.sceneView.session.run(configuration)

    self.gpuImageView = GPUImageView()
    self.gpuImageView.translatesAutoresizingMaskIntoConstraints = false

    //a delay for ARKit to capture the surroundings
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {

        // A SpriteKit scene to contain the SpriteKit video node
        let spriteKitScene = SKScene(size: CGSize(width: self.sceneView.frame.width, height: self.sceneView.frame.height))
        spriteKitScene.scaleMode = .aspectFit

        // Create a video player, which will be responsible for the playback of the video material
        guard let url = Bundle.main.url(forResource: "FY3A4278", withExtension: "mp4") else { return }
        let playerItem = AVPlayerItem(url: url)
        self.player.replaceCurrentItem(with: playerItem)

        //trans
        self.filter = GPUImageChromaKeyBlendFilter()
        self.filter.thresholdSensitivity = 0.15
        self.filter.smoothing = 0.3
        self.filter.setColorToReplaceRed(0.322, green: 0.455, blue: 0.831)

        self.movie = GPUImageMovie(playerItem: playerItem)
        self.movie.playAtActualSpeed = true
        self.movie.addTarget(self.filter)
        self.movie.startProcessing()

        let backgroundImage = UIImage(named: "transparent.png")
        self.sourcePicture = GPUImagePicture(image: backgroundImage, smoothlyScaleOutput: true)!
        self.sourcePicture.addTarget(self.filter)
        self.sourcePicture.processImage()

        ///HERE DON'T KNOW HOW TO CONTINUE ?
        self.filter.addTarget(self.gpuImageView)

        // To make the video loop
        self.player.actionAtItemEnd = .none
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(ARTransVC.playerItemDidReachEnd),
            name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
            object:  self.player.currentItem)

        // Create the SpriteKit video node, containing the video player
        let videoSpriteKitNode = SKVideoNode(avPlayer: self.player)
        videoSpriteKitNode.position = CGPoint(x: spriteKitScene.size.width / 2.0, y: spriteKitScene.size.height / 2.0)
        videoSpriteKitNode.size = spriteKitScene.size
        videoSpriteKitNode.yScale = -1.0
        videoSpriteKitNode.play()
        spriteKitScene.addChild(videoSpriteKitNode)

        // Create the SceneKit scene
        let scene = SCNScene()
        self.sceneView.scene = scene
        self.sceneView.isPlaying = true

        // Create a SceneKit plane and add the SpriteKit scene as its material
        let background = SCNPlane(width: CGFloat(1), height: CGFloat(1))
        background.firstMaterial?.diffuse.contents = spriteKitScene
        let backgroundNode = SCNNode(geometry: background)
        backgroundNode.geometry?.firstMaterial?.isDoubleSided = true

        backgroundNode.position = SCNVector3(0,0,-2.0)
        scene.rootNode.addChildNode(backgroundNode)
    }
}

@objc func playerItemDidReachEnd(notification: NSNotification) {
    if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem {
        playerItem.seek(to: kCMTimeZero, completionHandler: nil)
    }
}
}
</code>```

答:
So, I now managed to chroma-key and play a now transparent video in ARSCNView, but it still is a little patchy solution.

I stepped away from my former approach and implemented ChromaKeyMaterial from Lësha Turkowski!

Here it is, adjusted to the color I wanted to key:

```<code>import SceneKit

public class ChromaKeyMaterial: SCNMaterial {

public var backgroundColor: UIColor {
    didSet { didSetBackgroundColor() }
}

public var thresholdSensitivity: Float {
    didSet { didSetThresholdSensitivity() }
}

public var smoothing: Float  {
    didSet { didSetSmoothing() }
}

public init(backgroundColor: UIColor = .green, thresholdSensitivity: Float = 0.15, smoothing: Float = 0.0) {

    self.backgroundColor = backgroundColor
    self.thresholdSensitivity = thresholdSensitivity
    self.smoothing = smoothing

    super.init()

    didSetBackgroundColor()
    didSetThresholdSensitivity()
    didSetSmoothing()

    // chroma key shader is based on GPUImage
    // https://github.com/BradLarson/GPUImage/blob/master/framework/Source/GPUImageChromaKeyFilter.m

    let surfaceShader =
    """
    uniform vec3 c_colorToReplace;
    uniform float c_thresholdSensitivity;
    uniform float c_smoothing;

    #pragma transparent
    #pragma body

    vec3 textureColor = _surface.diffuse.rgb;

    float maskY = 0.2989 * c_colorToReplace.r + 0.5866 * c_colorToReplace.g + 0.1145 * c_colorToReplace.b;
    float maskCr = 0.7132 * (c_colorToReplace.r - maskY);
    float maskCb = 0.5647 * (c_colorToReplace.b - maskY);

    float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;
    float Cr = 0.7132 * (textureColor.r - Y);
    float Cb = 0.5647 * (textureColor.b - Y);

    float blendValue = smoothstep(c_thresholdSensitivity, c_thresholdSensitivity + c_smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));

    float a = blendValue;
    _surface.transparent.a = a;
    """

    //_surface.transparent.a = a;

    shaderModifiers = [
        .surface: surfaceShader,
    ]
}

required public init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

//setting background color to be keyed out
private func didSetBackgroundColor() {
//getting pixel from background color
//let rgb = backgroundColor.cgColor.components!.map{Float($0)}
//let vector = SCNVector3(x: rgb[0], y: rgb[1], z: rgb[2])
    let vector = SCNVector3(x: 0.216, y: 0.357, z: 0.663)
    setValue(vector, forKey: "c_colorToReplace")
}

private func didSetSmoothing() {
    setValue(smoothing, forKey: "c_smoothing")
}

private func didSetThresholdSensitivity() {
    setValue(thresholdSensitivity, forKey: "c_thresholdSensitivity")
}
}
</code>```

Here is the code that plays the keyed video in ARKit on a SCNPlane:

```<code>import UIKit
import ARKit

class ARTransVC: UIViewController{

@IBOutlet weak var arSceneView: ARSCNView!
let configuration = ARWorldTrackingConfiguration()

private var player: AVPlayer = {
    guard let url = Bundle.main.url(forResource: "FY3A4278", withExtension: "mp4") else { fatalError() }
    return AVPlayer(url: url)
}()

override func viewDidLoad() {
    super.viewDidLoad()
    self.arSceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints]
    self.arSceneView.session.run(configuration)

    //a delay for ARKit to capture the surroundings
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {

        // A SpriteKit scene to contain the SpriteKit video node
        let spriteKitScene = SKScene(size: CGSize(width: self.arSceneView.frame.width, height: self.arSceneView.frame.height))
        spriteKitScene.scaleMode = .aspectFit
        spriteKitScene.backgroundColor = .clear
        spriteKitScene.scaleMode = .aspectFit

        //Create the SpriteKit video node, containing the video player
        let videoSpriteKitNode = SKVideoNode(avPlayer: self.player)
        videoSpriteKitNode.position = CGPoint(x: spriteKitScene.size.width / 2.0, y: spriteKitScene.size.height / 2.0)
        videoSpriteKitNode.size = spriteKitScene.size
        videoSpriteKitNode.yScale = -1.0
        videoSpriteKitNode.play()
        spriteKitScene.addChild(videoSpriteKitNode)

        // To make the video loop
        self.player.actionAtItemEnd = .none
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(ARTransVC.playerItemDidReachEnd),
            name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
            object:  self.player.currentItem)

        // Create the SceneKit scene
        let scene = SCNScene()
        self.arSceneView.scene = scene

        //Create a SceneKit plane and add the SpriteKit scene as its material
        let background = SCNPlane(width: CGFloat(1), height: CGFloat(1))
        background.firstMaterial?.diffuse.contents = spriteKitScene
        let chromaKeyMaterial = ChromaKeyMaterial()
        chromaKeyMaterial.diffuse.contents = self.player

        let backgroundNode = SCNNode(geometry: background)
        backgroundNode.geometry?.firstMaterial?.isDoubleSided = true
        backgroundNode.geometry!.materials = [chromaKeyMaterial]

        backgroundNode.position = SCNVector3(0,0,-2.0)
        scene.rootNode.addChildNode(backgroundNode)

        //video does not start without delaying the player
        //playing the video before just results in [SceneKit] Error: Cannot get pixel buffer (CVPixelBufferRef)
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.player.seek(to:CMTimeMakeWithSeconds(1, 1000))
            self.player.play()
        }
    }
}

@objc func playerItemDidReachEnd(notification: NSNotification) {
    if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem {
        playerItem.seek(to: kCMTimeZero, completionHandler: nil)
    }
}
</code>```

I was getting a [SceneKit] Error: Cannot get pixel buffer (CVPixelBufferRef), which was apparently fixed in iOS 11.2. For now, I just found a rather patchy solution were I restarted the video after a one second delay. A better approach for that is greatly appreciated.

Body:
I am trying to play a video, showing transparency in an ARSCNView. A SCNPlane is used as a projection space for the video and I am trying to color key this video with GPUImage.

I followed this example here. Unfortunately, I have not found a way to project that video back on my videoSpriteKitNode. Because the filter is rendered in a GPUImageView, and the SKVideoNode takes a AVPlayer.

I am not sure if it is possible at all, what I am trying to do, so if anyone could share their insight I'd be very thankful!

import UIKit
import ARKit
import GPUImage

class ARTransVC: UIViewController{

@IBOutlet weak var sceneView: ARSCNView!
let configuration = ARWorldTrackingConfiguration()
var movie: GPUImageMovie!
var filter: GPUImageChromaKeyBlendFilter!
var sourcePicture: GPUImagePicture!
var player = AVPlayer()
var gpuImageView: GPUImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints]
    self.sceneView.session.run(configuration)

    self.gpuImageView = GPUImageView()
    self.gpuImageView.translatesAutoresizingMaskIntoConstraints = false

    //a delay for ARKit to capture the surroundings
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {

        // A SpriteKit scene to contain the SpriteKit video node
        let spriteKitScene = SKScene(size: CGSize(width: self.sceneView.frame.width, height: self.sceneView.frame.height))
        spriteKitScene.scaleMode = .aspectFit

        // Create a video player, which will be responsible for the playback of the video material
        guard let url = Bundle.main.url(forResource: "FY3A4278", withExtension: "mp4") else { return }
        let playerItem = AVPlayerItem(url: url)
        self.player.replaceCurrentItem(with: playerItem)

        //trans
        self.filter = GPUImageChromaKeyBlendFilter()
        self.filter.thresholdSensitivity = 0.15
        self.filter.smoothing = 0.3
        self.filter.setColorToReplaceRed(0.322, green: 0.455, blue: 0.831)

        self.movie = GPUImageMovie(playerItem: playerItem)
        self.movie.playAtActualSpeed = true
        self.movie.addTarget(self.filter)
        self.movie.startProcessing()

        let backgroundImage = UIImage(named: "transparent.png")
        self.sourcePicture = GPUImagePicture(image: backgroundImage, smoothlyScaleOutput: true)!
        self.sourcePicture.addTarget(self.filter)
        self.sourcePicture.processImage()

        ///HERE DON'T KNOW HOW TO CONTINUE ?
        self.filter.addTarget(self.gpuImageView)

        // To make the video loop
        self.player.actionAtItemEnd = .none
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(ARTransVC.playerItemDidReachEnd),
            name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
            object:  self.player.currentItem)

        // Create the SpriteKit video node, containing the video player
        let videoSpriteKitNode = SKVideoNode(avPlayer: self.player)
        videoSpriteKitNode.position = CGPoint(x: spriteKitScene.size.width / 2.0, y: spriteKitScene.size.height / 2.0)
        videoSpriteKitNode.size = spriteKitScene.size
        videoSpriteKitNode.yScale = -1.0
        videoSpriteKitNode.play()
        spriteKitScene.addChild(videoSpriteKitNode)

        // Create the SceneKit scene
        let scene = SCNScene()
        self.sceneView.scene = scene
        self.sceneView.isPlaying = true

        // Create a SceneKit plane and add the SpriteKit scene as its material
        let background = SCNPlane(width: CGFloat(1), height: CGFloat(1))
        background.firstMaterial?.diffuse.contents = spriteKitScene
        let backgroundNode = SCNNode(geometry: background)
        backgroundNode.geometry?.firstMaterial?.isDoubleSided = true

        backgroundNode.position = SCNVector3(0,0,-2.0)
        scene.rootNode.addChildNode(backgroundNode)
    }
}

@objc func playerItemDidReachEnd(notification: NSNotification) {
    if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem {
        playerItem.seek(to: kCMTimeZero, completionHandler: nil)
    }
}
}

Body:
So, I now managed to chroma-key and play a now transparent video in ARSCNView, but it still is a little patchy solution.

I stepped away from my former approach and implemented ChromaKeyMaterial from Lësha Turkowski!

Here it is, adjusted to the color I wanted to key:

import SceneKit

public class ChromaKeyMaterial: SCNMaterial {

public var backgroundColor: UIColor {
    didSet { didSetBackgroundColor() }
}

public var thresholdSensitivity: Float {
    didSet { didSetThresholdSensitivity() }
}

public var smoothing: Float  {
    didSet { didSetSmoothing() }
}

public init(backgroundColor: UIColor = .green, thresholdSensitivity: Float = 0.15, smoothing: Float = 0.0) {

    self.backgroundColor = backgroundColor
    self.thresholdSensitivity = thresholdSensitivity
    self.smoothing = smoothing

    super.init()

    didSetBackgroundColor()
    didSetThresholdSensitivity()
    didSetSmoothing()

    // chroma key shader is based on GPUImage
    // https://github.com/BradLarson/GPUImage/blob/master/framework/Source/GPUImageChromaKeyFilter.m

    let surfaceShader =
    """
    uniform vec3 c_colorToReplace;
    uniform float c_thresholdSensitivity;
    uniform float c_smoothing;

    #pragma transparent
    #pragma body

    vec3 textureColor = _surface.diffuse.rgb;

    float maskY = 0.2989 * c_colorToReplace.r + 0.5866 * c_colorToReplace.g + 0.1145 * c_colorToReplace.b;
    float maskCr = 0.7132 * (c_colorToReplace.r - maskY);
    float maskCb = 0.5647 * (c_colorToReplace.b - maskY);

    float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;
    float Cr = 0.7132 * (textureColor.r - Y);
    float Cb = 0.5647 * (textureColor.b - Y);

    float blendValue = smoothstep(c_thresholdSensitivity, c_thresholdSensitivity + c_smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));

    float a = blendValue;
    _surface.transparent.a = a;
    """

    //_surface.transparent.a = a;

    shaderModifiers = [
        .surface: surfaceShader,
    ]
}

required public init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

//setting background color to be keyed out
private func didSetBackgroundColor() {
//getting pixel from background color
//let rgb = backgroundColor.cgColor.components!.map{Float($0)}
//let vector = SCNVector3(x: rgb[0], y: rgb[1], z: rgb[2])
    let vector = SCNVector3(x: 0.216, y: 0.357, z: 0.663)
    setValue(vector, forKey: "c_colorToReplace")
}

private func didSetSmoothing() {
    setValue(smoothing, forKey: "c_smoothing")
}

private func didSetThresholdSensitivity() {
    setValue(thresholdSensitivity, forKey: "c_thresholdSensitivity")
}
}

Here is the code that plays the keyed video in ARKit on a SCNPlane:

import UIKit
import ARKit

class ARTransVC: UIViewController{

@IBOutlet weak var arSceneView: ARSCNView!
let configuration = ARWorldTrackingConfiguration()

private var player: AVPlayer = {
    guard let url = Bundle.main.url(forResource: "FY3A4278", withExtension: "mp4") else { fatalError() }
    return AVPlayer(url: url)
}()

override func viewDidLoad() {
    super.viewDidLoad()
    self.arSceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints]
    self.arSceneView.session.run(configuration)

    //a delay for ARKit to capture the surroundings
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {

        // A SpriteKit scene to contain the SpriteKit video node
        let spriteKitScene = SKScene(size: CGSize(width: self.arSceneView.frame.width, height: self.arSceneView.frame.height))
        spriteKitScene.scaleMode = .aspectFit
        spriteKitScene.backgroundColor = .clear
        spriteKitScene.scaleMode = .aspectFit

        //Create the SpriteKit video node, containing the video player
        let videoSpriteKitNode = SKVideoNode(avPlayer: self.player)
        videoSpriteKitNode.position = CGPoint(x: spriteKitScene.size.width / 2.0, y: spriteKitScene.size.height / 2.0)
        videoSpriteKitNode.size = spriteKitScene.size
        videoSpriteKitNode.yScale = -1.0
        videoSpriteKitNode.play()
        spriteKitScene.addChild(videoSpriteKitNode)

        // To make the video loop
        self.player.actionAtItemEnd = .none
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(ARTransVC.playerItemDidReachEnd),
            name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
            object:  self.player.currentItem)

        // Create the SceneKit scene
        let scene = SCNScene()
        self.arSceneView.scene = scene

        //Create a SceneKit plane and add the SpriteKit scene as its material
        let background = SCNPlane(width: CGFloat(1), height: CGFloat(1))
        background.firstMaterial?.diffuse.contents = spriteKitScene
        let chromaKeyMaterial = ChromaKeyMaterial()
        chromaKeyMaterial.diffuse.contents = self.player

        let backgroundNode = SCNNode(geometry: background)
        backgroundNode.geometry?.firstMaterial?.isDoubleSided = true
        backgroundNode.geometry!.materials = [chromaKeyMaterial]

        backgroundNode.position = SCNVector3(0,0,-2.0)
        scene.rootNode.addChildNode(backgroundNode)

        //video does not start without delaying the player
        //playing the video before just results in [SceneKit] Error: Cannot get pixel buffer (CVPixelBufferRef)
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.player.seek(to:CMTimeMakeWithSeconds(1, 1000))
            self.player.play()
        }
    }
}

@objc func playerItemDidReachEnd(notification: NSNotification) {
    if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem {
        playerItem.seek(to: kCMTimeZero, completionHandler: nil)
    }
}

I was getting a [SceneKit] Error: Cannot get pixel buffer (CVPixelBufferRef), which was apparently fixed in iOS 11.2. For now, I just found a rather patchy solution were I restarted the video after a one second delay. A better approach for that is greatly appreciated.