问:
HttpUrlConnection.connect fails
I've been trying to create a small app that connects to url in editText and returns the status code.

Here is the onCreate code:

```<code> override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    button.setOnClickListener {
        val url = editText.text.toString()
        var connection: HttpURLConnection? = null
        if (URLUtil.isValidUrl(url)) {
            connection = URL(url).openConnection() as HttpURLConnection
            var thr = Thread {
                connection.connect()
                val code = connection.responseCode
                runOnUiThread {
                    if (code != 404 && code != 500) {
                        textView.text = "Ok"
                    } else {
                        textView.text = "Failed"
                    }
                }

            }
            thr.start()
            thr.join()
        } else {
            textView.text = "Failed"
        }
    }
</code>```

The problem is that whenever URL is valid, runtime error occurs in .connect() method. Internet permission is set up in android manifest. What causes that issue?

```<code>E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.example.company.myapplication, PID: 27183
java.net.SocketException: socket failed: EPERM (Operation not permitted)
    at java.net.Socket.createImpl(Socket.java:492)
    at java.net.Socket.getImpl(Socket.java:552)
    at java.net.Socket.setSoTimeout(Socket.java:1180)
    at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:143)
    at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
    at com.example.company.myapplication.MainActivity$onCreate$1$thr$1.run(MainActivity.kt:25)
    at java.lang.Thread.run(Thread.java:919)
</code>```

答:
Hi please check if you have provided the permission of internet in your manifest,</p>

```<code><manifest >
 <uses-permission android:name="android.permission.INTERNET" />
 <application>
  ...
 </application>
</manifest>
</code>```

Title: HttpUrlConnection.connect fails

Body:
I've been trying to create a small app that connects to url in editText and returns the status code.

Here is the onCreate code:

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    button.setOnClickListener {
        val url = editText.text.toString()
        var connection: HttpURLConnection? = null
        if (URLUtil.isValidUrl(url)) {
            connection = URL(url).openConnection() as HttpURLConnection
            var thr = Thread {
                connection.connect()
                val code = connection.responseCode
                runOnUiThread {
                    if (code != 404 && code != 500) {
                        textView.text = "Ok"
                    } else {
                        textView.text = "Failed"
                    }
                }

            }
            thr.start()
            thr.join()
        } else {
            textView.text = "Failed"
        }
    }

The problem is that whenever URL is valid, runtime error occurs in .connect() method. Internet permission is set up in android manifest. What causes that issue?

E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.example.company.myapplication, PID: 27183
java.net.SocketException: socket failed: EPERM (Operation not permitted)
    at java.net.Socket.createImpl(Socket.java:492)
    at java.net.Socket.getImpl(Socket.java:552)
    at java.net.Socket.setSoTimeout(Socket.java:1180)
    at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:143)
    at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
    at com.example.company.myapplication.MainActivity$onCreate$1$thr$1.run(MainActivity.kt:25)
    at java.lang.Thread.run(Thread.java:919)

Body:
Hi please check if you have provided the permission of internet in your manifest,

<manifest >
 <uses-permission android:name="android.permission.INTERNET" />
 <application>
  ...
 </application>
</manifest>


来源: stackexchange

问:
Http Request Send To BW
I have a html page with some form fields (like textbox, submit button etc) I want to call the BW process on click of the submit button, which will send the form fields value (textbox values) to the BW process definition.

BW Process definition will do some operation (like retrieve the database record) and send the result to the html page.

When I use http://localhost:9999, it will only call the BW process (Http receiver and Send HTTP Response) and the html page will populate with the string which i get from "Send HTTP Response" palette.

How can I embed that HTTP response into some text field of the response webpage along with few images and other fields already present in HTML page.

答:
Have you tried using the Generate Web Service form the Tools menu in Designer? Select the process you need to use then run this.

You first need to make sure that the process start & end has the correct parameters. I think it is best to use xml and an xsd, i.e. in output editor select content of XML Element Reference type, then select the correct schema and element.

Once you have the wsdl and the url you can call this just like any other web service.

ContentLicense: CC BY-SA 3.0

Title: Http Request Send To BW


问:
Why delegate object is nil?
I am facing little weird issue with delegate pattern and I couldn't make it work like I expect. I guess I am missing something here but I couldn't figure it out myself.

Here's how my classes are defined,

```<code>class NetworkManager {

    weak var delegate: DownloaderProtocol?

    func downloadFile(downloadUrl: URL ) {
        downloadTask(with: downloadUrl).resume()
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        delegate?.downloadCompleted(task: task, error: error)
    }
}

class DownloadManager: DownloaderProtocol {

    var networkManager: NetworkManager

    init(networkManager: NetworkManager) {
        self.networkManager = networkManager
    }

    func downloadMatches(urls: [String]) {
        self.networkManager.delegate = self

        for(....) {
            self.networkManager.downloadFile(url: url)
        }
    }

    func downloadCompleted(task: URLSessionTask, error: Error) {
        // Implementation
    }
}

class Matches {

    var networkManager: NetworkManager
    init() {
        self.networkManager = NetworkManager()
    }

    func getMatchSchedules(urls: [String] , completionHandler: @escaping (Result<Data, Error>) -> Void) {
        return DownloadManager.downloadMatches(urls: [String])
    }
}
</code>```

What is the issue ?

When the urlSession - didCompleteWithError method is called, I can see that delegate object is nil.

What I have tried ?

If I remove the weak reference of the delegate i.e weak var delegate: DownloaderProtocol? to var delegate: DownloaderProtocol?, then the delegate object is not nil. It works fine.

I even tried to set the delegates in Matches class, but the delegate is still shown as nil

Any help or point out is welcome.

答:
You can use callback in place of delegate.
It's much easier approach than delegate.

```<code>typealias APIServiceSuccessCallback = ((Any?) -> ())
</code>```

ViewController A:

```<code>//call from A -> B result fire if completionHandler fire in VC B
    addCompanyTargetsController.responseCreateBookingObj = { [unowned self] (returnObject) in
                    if let object = returnObject as? [String:Any] {
                        if object["success"] as? Bool == true {
                            self.loadTargetList()//success block
                        }
                    }
                }
</code>```

ViewController B:

```<code>var responseCreateBookingObj : APIServiceSuccessCallback? //declaration

func completionHandler() { //from where you fire call this method
        guard let callBack = self.responseCreateBookingObj else{
            return
        }
        callBack( true as AnyObject)
    }
</code>```

ContentLicense: CC BY-SA 4.0

Title: Why delegate object is nil?

Body:
I am facing little weird issue with delegate pattern and I couldn't make it work like I expect. I guess I am missing something here but I couldn't figure it out myself.

Here's how my classes are defined,

class NetworkManager {

    weak var delegate: DownloaderProtocol?

    func downloadFile(downloadUrl: URL ) {
        downloadTask(with: downloadUrl).resume()
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        delegate?.downloadCompleted(task: task, error: error)
    }
}

class DownloadManager: DownloaderProtocol {

    var networkManager: NetworkManager

    init(networkManager: NetworkManager) {
        self.networkManager = networkManager
    }

    func downloadMatches(urls: [String]) {
        self.networkManager.delegate = self

        for(....) {
            self.networkManager.downloadFile(url: url)
        }
    }

    func downloadCompleted(task: URLSessionTask, error: Error) {
        // Implementation
    }
}

class Matches {

    var networkManager: NetworkManager
    init() {
        self.networkManager = NetworkManager()
    }

    func getMatchSchedules(urls: [String] , completionHandler: @escaping (Result<Data, Error>) -> Void) {
        return DownloadManager.downloadMatches(urls: [String])
    }
}

What is the issue ?

When the urlSession - didCompleteWithError method is called, I can see that delegate object is nil.

What I have tried ?

If I remove the weak reference of the delegate i.e weak var delegate: DownloaderProtocol? to var delegate: DownloaderProtocol?, then the delegate object is not nil. It works fine.

I even tried to set the delegates in Matches class, but the delegate is still shown as nil

Any help or point out is welcome.

Body:
You can use callback in place of delegate.
It's much easier approach than delegate.

typealias APIServiceSuccessCallback = ((Any?) -> ())

ViewController A:

//call from A -> B result fire if completionHandler fire in VC B
    addCompanyTargetsController.responseCreateBookingObj = { [unowned self] (returnObject) in
                    if let object = returnObject as? [String:Any] {
                        if object["success"] as? Bool == true {
                            self.loadTargetList()//success block
                        }
                    }
                }

ViewController B:

var responseCreateBookingObj : APIServiceSuccessCallback? //declaration

func completionHandler() { //from where you fire call this method
        guard let callBack = self.responseCreateBookingObj else{
            return
        }
        callBack( true as AnyObject)
    }


问:
Use an objects name to make changes to the object
I have created multiple instances of one object each with there own instance names with numbers on the end. I would like to iterate through these names (they have numbers on the end), modify there properties then push them to an array all through the instance names not the actual object instances.

```<code>if (instance60.currentFrame == 4)
{
    array.push("instance60")
}
</code>```

Where the first instance60 is refering to the object itself and the second instance60 is just a pushed string

答:
I think what you are looking to do is set a key value pair.

The key would be how you find the reference to the object later

```<code>instances["instance"+60] = instance60;
</code>```

you can loop using something like:

```<code>for(var i:uint=0;i<instances.length;i++){
   instances["instance"+i] = new Sprite();
   instances["instance"+i].x = 20;
   instances["instance"+i].y = 20*i;
   //etc...
}
</code>```

But, although this has it's uses, in this case you are iterating through an integer value anyways, so, given it can run quite a bit faster on large arrays, why not just store them at their position in the array?

```<code>for(var i:uint=0;i<instances.length;i++){
       instances[i] = new Sprite();
       instances[i].x = 20;
       instances[i].y = 20*i;
       this.addChild(instance[i]);
       //etc...
    }
</code>```

Body:
I have created multiple instances of one object each with there own instance names with numbers on the end. I would like to iterate through these names (they have numbers on the end), modify there properties then push them to an array all through the instance names not the actual object instances.

if (instance60.currentFrame == 4)
{
    array.push("instance60")
}

Where the first instance60 is refering to the object itself and the second instance60 is just a pushed string

Body:
I think what you are looking to do is set a key value pair.

The key would be how you find the reference to the object later

instances["instance"+60] = instance60;

you can loop using something like:

for(var i:uint=0;i<instances.length;i++){
   instances["instance"+i] = new Sprite();
   instances["instance"+i].x = 20;
   instances["instance"+i].y = 20*i;
   //etc...
}

But, although this has it's uses, in this case you are iterating through an integer value anyways, so, given it can run quite a bit faster on large arrays, why not just store them at their position in the array?

for(var i:uint=0;i<instances.length;i++){
       instances[i] = new Sprite();
       instances[i].x = 20;
       instances[i].y = 20*i;
       this.addChild(instance[i]);
       //etc...
    }


问:
Gradle - Run Application From Test Module
I currently have the following gradle to run an application

```<code>apply plugin: 'application'

application {
    mainClassName = 'com.Example'
}
</code>```

This doesn't work as the Example class is in the test module as it's not meant to be released in production code. Is there any way to specify to gradle to look in the test module, instead of the main module?

答:
Solution was to not use the application module; instead...

```<code>apply plugin: 'java'

task runExample(type: JavaExec) {
    classpath = sourceSets.test.runtimeClasspath
    main = 'com.Example'
}
</code>```

Body:
I currently have the following gradle to run an application

apply plugin: 'application'

application {
    mainClassName = 'com.Example'
}

This doesn't work as the Example class is in the test module as it's not meant to be released in production code. Is there any way to specify to gradle to look in the test module, instead of the main module?

Body:
Solution was to not use the application module; instead...

apply plugin: 'java'

task runExample(type: JavaExec) {
    classpath = sourceSets.test.runtimeClasspath
    main = 'com.Example'
}


问:
Compile Unreal Lightmass. Error with Unreal 4.24 build from source on Linux
I get the following error when I am trying to build a project in Unreal, that I have included some lightning. "Lighting Build Failed. Swarm failed to Kick off. Compile Unreal Lightmass".

I have build Unreal Engine 4.24.1 from source on Linux with the setup instructions from the documentations.

Any ideas how to proceed. How would I go and compile Unreal Lightmass for the Engine?

答:
After some sparse search here and there, I was able to solve this.
To compile the UnrealLightmass there is a build shell script in the directory

```<code>UnrealEngine_Repo_dir/Engine/Build/BatchFiles/Linux
</code>```

You need to run the ./Build.sh with the following input

```<code>./UnrealEngine_Repo_dir/Engine/Build/BatchFiles/Linux/Build.sh UnrealLightmass Linux Development -verbose
</code>```

This should start compilation and build the UnrealLightmass.
This probably is the way to build the remaining programs that the Unreal Engine would complain that you haven't build.
Any program that is under the directory

```<code>/UnrealEngine_Repo_dir/Engine/Source/Programs
</code>```

can be build with the above command. One example would be the ShaderCompileWorker.

Hope this helps.

Body:
After some sparse search here and there, I was able to solve this.
To compile the UnrealLightmass there is a build shell script in the directory

UnrealEngine_Repo_dir/Engine/Build/BatchFiles/Linux

You need to run the ./Build.sh with the following input

./UnrealEngine_Repo_dir/Engine/Build/BatchFiles/Linux/Build.sh UnrealLightmass Linux Development -verbose

This should start compilation and build the UnrealLightmass.
This probably is the way to build the remaining programs that the Unreal Engine would complain that you haven't build.
Any program that is under the directory

/UnrealEngine_Repo_dir/Engine/Source/Programs

can be build with the above command. One example would be the ShaderCompileWorker.

Hope this helps.


问:
pip install keras-retinanet==0.5.0 OSError: [WinError 193] %1 is not a valid Win32 application
I'm having an issue installing a dependency called keras-retinanet.

I'm having a hard time making out what the error is telling me.

$ pip install keras-retinanet==0.5.0
Collecting keras-retinanet==0.5.0
  Using cached keras-retinanet-0.5.0.tar.gz (59 kB)
    ERROR: Command errored out with exit status 1:
     command: 'c:\users\nicol\appdata\local\programs\python\python37\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Nicol\\AppData\\Local\\Temp\\pip-install-v20g1wmz\\keras-retinanet\\setup.py'"'"'; __file__='"'"'C:\\Users\\Nicol\\AppData\\Local\\Temp\\pip-install-v20g1wmz\\keras-retinanet\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\Nicol\AppData\Local\Temp\pip-install-v20g1wmz\keras-retinanet\pip-egg-info'
         cwd: C:\Users\Nicol\AppData\Local\Temp\pip-install-v20g1wmz\keras-retinanet\
    Complete output (11 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\Nicol\AppData\Local\Temp\pip-install-v20g1wmz\keras-retinanet\setup.py", line 3, in <module>
        import numpy as np
      File "C:\Users\Nicol\AppData\Roaming\Python\Python37\site-packages\numpy\__init__.py", line 140, in <module>
        from . import _distributor_init
      File "C:\Users\Nicol\AppData\Roaming\Python\Python37\site-packages\numpy\_distributor_init.py", line 26, in <module>
        WinDLL(os.path.abspath(filename))
      File "c:\users\nicol\appdata\local\programs\python\python37\lib\ctypes\__init__.py", line 364, in __init__
        self._handle = _dlopen(self._name, mode)
    OSError: [WinError 193] %1 is not a valid Win32 application
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

```

Aditional info:

<p>Python version : </p>

<pre class="lang-sh prettyprint-override"><code>Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)]
</code>```

pip version

pip-20.0.2
```

答:
pip uninstall numpy

pip install numpy

did the trick

Body:
I'm having an issue installing a dependency called keras-retinanet.

I'm having a hard time making out what the error is telling me.

$ pip install keras-retinanet==0.5.0
Collecting keras-retinanet==0.5.0
  Using cached keras-retinanet-0.5.0.tar.gz (59 kB)
    ERROR: Command errored out with exit status 1:
     command: 'c:\users\nicol\appdata\local\programs\python\python37\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Nicol\\AppData\\Local\\Temp\\pip-install-v20g1wmz\\keras-retinanet\\setup.py'"'"'; __file__='"'"'C:\\Users\\Nicol\\AppData\\Local\\Temp\\pip-install-v20g1wmz\\keras-retinanet\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\Nicol\AppData\Local\Temp\pip-install-v20g1wmz\keras-retinanet\pip-egg-info'
         cwd: C:\Users\Nicol\AppData\Local\Temp\pip-install-v20g1wmz\keras-retinanet\
    Complete output (11 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\Nicol\AppData\Local\Temp\pip-install-v20g1wmz\keras-retinanet\setup.py", line 3, in <module>
        import numpy as np
      File "C:\Users\Nicol\AppData\Roaming\Python\Python37\site-packages\numpy\__init__.py", line 140, in <module>
        from . import _distributor_init
      File "C:\Users\Nicol\AppData\Roaming\Python\Python37\site-packages\numpy\_distributor_init.py", line 26, in <module>
        WinDLL(os.path.abspath(filename))
      File "c:\users\nicol\appdata\local\programs\python\python37\lib\ctypes\__init__.py", line 364, in __init__
        self._handle = _dlopen(self._name, mode)
    OSError: [WinError 193] %1 is not a valid Win32 application
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

Aditional info:

Python version :

Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)]

pip version

pip-20.0.2


问:
Typescript filter adult and child
The filter is not working properly. I want to filter the adults with their child numbers and include them in the records. How can I fix the code?

.html

```<code><input id="adult" type="number" [(ngModel)]="adult" (ngModelChange)="changeNumberOfAdults()" />
<input id="child" type="number" max="3" min="0" [(ngModel)]="childCount" [(ngModel)]="chd" (ngModelChange)="changeNumberOfChilds()" />
</code>```

.ts

```<code>changeNumberOfAdults() {
    const filtered = this.hotels.filter(x => x.numberOfAd == this.adult);
    this.dsHotels.data = filtered;
}

changeNumberOfChilds() {
    const filtered = this.hotels.filter(x => x.numberOfChd == this.chd);
    this.dsHotels.data = filtered; }
</code>```

答:
Just have a single function, e.g:

```<code>filterHotels() {
    const filtered = this.hotels.filter(x => x.numberOfAd == this.adult && x.numberOfChd == this.chd);
    this.dsHotels.data = filtered;
}
</code>```

Then:

```<code><input id="adult" type="number" [(ngModel)]="adult" (ngModelChange)="filterHotels()" />
<input id="child" type="number" max="3" min="0" [(ngModel)]="chd" (ngModelChange)="filterHotels()" />
</code>```

And yes you should only have one ngModel on an input so remove

```<code>[(ngModel)]="childCount"
</code>```

See StackBlitz working example.

As the values are stored in the adult and chd variables in your .ts file, the values are always available to the function so a single function can filter on both values no matter which model change triggers it.

Note, you should be able to add any of the other filter variables to this function too and just call it from all your inputs.

Title: Typescript filter adult and child

Body:
The filter is not working properly. I want to filter the adults with their child numbers and include them in the records. How can I fix the code?

.html

<input id="adult" type="number" [(ngModel)]="adult" (ngModelChange)="changeNumberOfAdults()" />
<input id="child" type="number" max="3" min="0" [(ngModel)]="childCount" [(ngModel)]="chd" (ngModelChange)="changeNumberOfChilds()" />

.ts

changeNumberOfAdults() {
    const filtered = this.hotels.filter(x => x.numberOfAd == this.adult);
    this.dsHotels.data = filtered;
}

changeNumberOfChilds() {
    const filtered = this.hotels.filter(x => x.numberOfChd == this.chd);
    this.dsHotels.data = filtered; }

Body:
Just have a single function, e.g:

filterHotels() {
    const filtered = this.hotels.filter(x => x.numberOfAd == this.adult && x.numberOfChd == this.chd);
    this.dsHotels.data = filtered;
}

Then:

<input id="adult" type="number" [(ngModel)]="adult" (ngModelChange)="filterHotels()" />
<input id="child" type="number" max="3" min="0" [(ngModel)]="chd" (ngModelChange)="filterHotels()" />

And yes you should only have one ngModel on an input so remove

[(ngModel)]="childCount"

See StackBlitz working example.

As the values are stored in the adult and chd variables in your .ts file, the values are always available to the function so a single function can filter on both values no matter which model change triggers it.

Note, you should be able to add any of the other filter variables to this function too and just call it from all your inputs.


问:
Xamarin.forms android Prism handle hardware back button
I am having issue while handling back button on android device. I want to handle navigation stack while user press hardware back button how I can achieve this?</p>

答:
I don't know it's a good practice, but it worked to me.

```<code>protected override bool OnBackButtonPressed()
{
    var vm = (SignInViewModel)BindingContext;

    vm.GoBackCommand.Execute();

    return base.OnBackButtonPressed();
}
</code>```

At ViewModel you can handle what you want to perform.

Body:
I don't know it's a good practice, but it worked to me.

protected override bool OnBackButtonPressed()
{
    var vm = (SignInViewModel)BindingContext;

    vm.GoBackCommand.Execute();

    return base.OnBackButtonPressed();
}

At ViewModel you can handle what you want to perform.


问:
Business Model + Database Mapper + Joins
I am studying business models and UML. I read that a 'Model' is a series of 'Business Objects'.

From what I have understood a model would be 'Blog' whereas the business objects could be 'Post' and 'Comment'. The 'Blog' decides which objects to use and how they are to be persisted with appropriate mappers.

I have thrown together a few UML diagrams to explore this concept and it does seem quite logical. However I am a little confused:

Issue #1 - In Joomla models appear to represent a singular 'Business Object' (as opposed to coordinating multiple business objects and mappers). Does Joomla adopt a different approach to models?

Issue #2 - Is it acceptable for 'Mapper' objects to perform left joins in queries? Or should this kind of logic be moved into the 'Service' layer?

It seems most logical to utilise left join capabilities of the database, but I cannot figure out how this fits into (Mapper + BusinessObject + Model + Service) design.

答:
In a lot of frameworks and apps you will find that a Model = Business Object and that often times the Mapper is internalized into some kind of singular base model that all others extend. You'll also find that many of them lack a well defined service layer.

This feeds in to your second question about the mapper and service. I usually dont use service layer, but ideally you mapper would be fed the data from the DB which i suppose would typically reside in the service layer, then it maps that data into the business objects. However, When using a mapper i often integrate the table specific db logic directly into the mapper in the private or protected scope.

However in most cases im using an ORM that typically implements Active Record so there is no real isolation of the mapper per se in terms of how you are describing it, then tend to function in the way i described above in my first paragraph.

Also Joomla is probably not the best app to study these concepts with. Actually most PHP apps like this arent really good examples whether its Joomla, PHPBB, Drupal or otherwise :-)


问:
How to draw a range label on x axis using chartJS
I want a range indicator on the x axis as in the image -

I tried some annotations plugins like chartjs-plugin-annotation.js but they dont seem to support such a feature.

More generally, is there a specific term for such a label? "Range indicator label" doesn't bring up anything related to this.

答:
Look, in versions 2.1.5 forward you can use nested labels and kind of get the desired behavior: a second line of labels, where you can show secondary information in certain places.

```<code>var data = {
      labels: [['2015','Backtested'], '2016', '2017', ['2018', 'Live'], '2019', '2020'],

          datasets: [
            {
              label: "Set 1",
              data: [ 100, 200, 150, 250, 270, 300 ],
              backgroundColor: 'rgba(54, 162, 235, 0.2)',
              borderColor: 'rgba(54, 162, 235, 1)',
              borderWidth: 1
            },
            {
              label: "Set 2",
              data: [ 60, 250, 130, 300, 330, 340 ],
              backgroundColor: 'rgba(255, 99, 132, 0.2)',
              borderColor: 'rgba(255,99,132,1)',
              borderWidth: 1
            }
          ]
    };

var canvas = document.getElementById('chart');
new Chart(canvas, {
  type: 'line',
  data: data,
  options: {
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }],
      xAxes: [{

      }]
    }
  }
});
</code>```

JSFiddle

Kudos:

[1] ChartJS New Lines '\n' in X axis Labels or Displaying More Information Around Chart or Tooltip with ChartJS V2

UPDATE:

I had to make little more workout to get the same work in time series (where you do not define labels directly by yourself, EXCEPT with a Tick callback) and finally got the results like shown here:

```<code>var canvas = document.getElementById('chart');

var s1 = [{x:"2017-01-06 18:39:30",y:"70"}, {x:"2017-01-07 18:39:30",y:"100"},{x:"2017-01-08 08:39:28",y:"101"}];
var s2 = [{x:"2017-01-06 08:39:30",y:"100"},{x:"2017-01-07 18:00:00",y:"90"},{x:"2017-01-08 18:00:00",y:"105"}];

var graphParams = {
    type:"line",
  data:{
        datasets: [{
            label:"Series 1",
            data:s1,
            borderColor:"red",
            backgroundColor:"transparent",
      xAxesGroup:"A"
        },
        {
            label:"Series 2",
            data:s2,
            borderColor:"blue",
            backgroundColor:"transparent",
      xAxesGroup:"A"
        },
    ],
    },
    options:{
        maintainAspectRatio:false,
        responsive:true,
        scales:{
            xAxes:[{
        name:"A",
                type:"time",
                distribution: "linear",
        },
        {
        name:"B",
        type:"time",
        time: {
          unit: 'day'
        },
        ticks: {
            callback: function(value, index, values) {
               if (value == "Jan 7, 2017") {
                    return "Start";
               } else if (value == "Jan 8, 2017") {
                    return "Live";
               } else {
                    return "";
               }
            }
            }
        }
      ],
    }
    }
 };

ctx = new Chart(canvas, graphParams);
</code>```

JSFiddle tells the results in live.

Important notes: I needed a name for xAxes and map it to data with xAxesGroup and a B group with no data, where I attached the custom handler for titles and made the resolution in days, so that there are identifiable place for the label in chart.

Body:
Look, in versions 2.1.5 forward you can use nested labels and kind of get the desired behavior: a second line of labels, where you can show secondary information in certain places.

var data = {
      labels: [['2015','Backtested'], '2016', '2017', ['2018', 'Live'], '2019', '2020'],

          datasets: [
            {
              label: "Set 1",
              data: [ 100, 200, 150, 250, 270, 300 ],
              backgroundColor: 'rgba(54, 162, 235, 0.2)',
              borderColor: 'rgba(54, 162, 235, 1)',
              borderWidth: 1
            },
            {
              label: "Set 2",
              data: [ 60, 250, 130, 300, 330, 340 ],
              backgroundColor: 'rgba(255, 99, 132, 0.2)',
              borderColor: 'rgba(255,99,132,1)',
              borderWidth: 1
            }
          ]
    };

var canvas = document.getElementById('chart');
new Chart(canvas, {
  type: 'line',
  data: data,
  options: {
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }],
      xAxes: [{

      }]
    }
  }
});

JSFiddle

Kudos:

[1] ChartJS New Lines '\n' in X axis Labels or Displaying More Information Around Chart or Tooltip with ChartJS V2

UPDATE:

I had to make little more workout to get the same work in time series (where you do not define labels directly by yourself, EXCEPT with a Tick callback) and finally got the results like shown here:

var canvas = document.getElementById('chart');

var s1 = [{x:"2017-01-06 18:39:30",y:"70"}, {x:"2017-01-07 18:39:30",y:"100"},{x:"2017-01-08 08:39:28",y:"101"}];
var s2 = [{x:"2017-01-06 08:39:30",y:"100"},{x:"2017-01-07 18:00:00",y:"90"},{x:"2017-01-08 18:00:00",y:"105"}];

var graphParams = {
    type:"line",
  data:{
        datasets: [{
            label:"Series 1",
            data:s1,
            borderColor:"red",
            backgroundColor:"transparent",
      xAxesGroup:"A"
        },
        {
            label:"Series 2",
            data:s2,
            borderColor:"blue",
            backgroundColor:"transparent",
      xAxesGroup:"A"
        },
    ],
    },
    options:{
        maintainAspectRatio:false,
        responsive:true,
        scales:{
            xAxes:[{
        name:"A",
                type:"time",
                distribution: "linear",
        },
        {
        name:"B",
        type:"time",
        time: {
          unit: 'day'
        },
        ticks: {
            callback: function(value, index, values) {
               if (value == "Jan 7, 2017") {
                    return "Start";
               } else if (value == "Jan 8, 2017") {
                    return "Live";
               } else {
                    return "";
               }
            }
            }
        }
      ],
    }
    }
 };

ctx = new Chart(canvas, graphParams);

JSFiddle tells the results in live.

Important notes: I needed a name for xAxes and map it to data with xAxesGroup and a B group with no data, where I attached the custom handler for titles and made the resolution in days, so that there are identifiable place for the label in chart.


问:
issue with my main method in my connect4 game
Im having a problem with my main method, whenevr I run it my code cant compile because of this problem :
"Exception in thread "main" java.lang.NullPointerException
    at UI.ConnectFourFrame.refreshUI(ConnectFourFrame.java:96)
    at UI.ConnectFourFrame.(ConnectFourFrame.java:43)
    at main.main(main.java:11)"

I am trying to see what the issue is but I cant figure it out, can someone help me

```<code>package Game;

import java.util.ArrayList;

public class ConnectFourBoard {

    // This constant is used to indicate the width and height, in cells,
    // of the board.  Since we want an 8x8 board, we'll set it to 8.
    private static final int WIDTH = 7;
    private static final int HEIGHT = 6;
    private ConnectFourCell[][] currentPlayer;

    // The current state the Othello board is defined with these two
    // fields: a two-dimensional array holding the state of each cell,
    // and a boolean value indicating whether it's the black player's
    // turn (true) or the white player's turn (false).
    private ConnectFourCell[][] cells;
    private boolean isBlueTurn;

    // Since the board is a model and it needs to notify views of changes,
    // it will employ the standard "listener" mechanism of tracking a list
    // of listeners and firing "events" (by calling methods on those
    // listeners) when things change.
    private ArrayList<ConnectFourListener> listeners;

    public ConnectFourBoard()
    {
        // Arrays, in Java, are objects, which means that variables of
        // array types (like cells, which has type OthelloCell[][]) are
        // really references that say where an array lives.  By default,
        // references point to null.  So we'll need to create an actual
        // two-dimensional array for "cells" to point to.
        cells = new ConnectFourCell[WIDTH][HEIGHT];
        listeners = new ArrayList<ConnectFourListener>();
        reset();
    }

    public void reset(){
        for (int i = 0; i<WIDTH ; i++){
            for (int j = 0; j<HEIGHT; j++){

                cells[i][j] = ConnectFourCell.NONE;
            }
        }

        isBlueTurn = true;
    }

    public void addConnectFourListener(ConnectFourListener listener)
    {
        listeners.add(listener);
    }

    public void removeConnectFourListener(ConnectFourListener listener)
    {
        if (listeners.contains(listener))
        {
            listeners.remove(listener);
        }
    }

    // These are fairly standard "fire event" methods that we've been building
    // all quarter, one corresponding to each method in the listener interface.

    private void fireBoardChanged()
    {
        for (ConnectFourListener listener : listeners)
        {
            listener.boardChanged();
        }
    }

    private void fireGameOver()
    {
        for (ConnectFourListener listener : listeners)
        {
            listener.gameOver();
        }
    }

    // isBlackTurn() returns true if it's the black player's turn, and false
    // if it's the white player's turn.
    public boolean isBlueTurn()
    {
        return isBlueTurn;
    }

    public int getWidth()
    {
        return WIDTH;

    }

    public int getHeight(){

        return HEIGHT;
    }
    // getBlackScore() calculates the score for the black player.
    public int getBlackScore()
    {
        return getScore(ConnectFourCell.BLUE);
    }

    // getWhiteScore() calculates the score for the white player.
    public int getWhiteScore()
    {
        return getScore(ConnectFourCell.RED);
    }

    // getScore() runs through all the cells on the board and counts the
    // number of cells that have a particular value (e.g., BLACK or WHITE).
    // This method uses the naive approach of counting them each time
    // it's called; it might be better to keep track of this score as we
    // go, updating it as tiles are added and flipped.
    private int getScore(ConnectFourCell cellValue)
    {
        int score = 0;

        for (int i = 0; i < WIDTH; i++)
        {
            for (int j = 0; j < HEIGHT; j++)
            {
                if (cells[i][j] == cellValue)
                {
                    score++;
                }
            }
        }

        return score;
    }

    // getWhiteScore() calculates the score for the white player.
    public int getRedScore()
    {
        return getScore(ConnectFourCell.RED);
    }

    public int getBlueScore() {
        // TODO Auto-generated method stub
        return getScore(ConnectFourCell.BLUE);
    }

    public ConnectFourCell getCell(int x, int y)
    {
        if (!isValidCell(x, y))
        {
            throw new IllegalArgumentException(
                "(" + x + ", " + y + ") is not a valid cell");
        }

        return cells[x][y];
    }
    /**
    * The drop method.
    *
    * Drop a checker into the specified HEIGHT,
    * and return the WIDTH that the checker lands on.
    */
    int drop(int HEIGHT) {
    if (hasWon()) {
    return -1;
    }

    for ( ; WIDTH<6 && HEIGHT != 0; WIDTH++) { };

    if (WIDTH==6) {
    // if the WIDTH is 6, it went through all 6 WIDTHs
    // of the cells, and couldn't find an empty one.
    // Therefore, return false to indicate that this
    // drop operation failed.
    return -1;
    }
    // fill the WIDTH of that HEIGHT with a checker.
    cells[HEIGHT][WIDTH] = currentPlayer[HEIGHT][WIDTH];
    // alternate the players
    //currentPlayer = (currentPlayer%2)+1;
    return WIDTH;
    }
    /**
    * The toString method
    *
    * Returns a String representation of this
    * Connect Four (TM) game.
    */
    public String toString() {
    String returnString = "";
    for (int WIDTH=5; WIDTH>=0; WIDTH--) {
    for (int HEIGHT=0; HEIGHT<7; HEIGHT++) {
    returnString = returnString + cells[HEIGHT][WIDTH];
    }
    returnString = returnString + "\n";
    }
    return returnString;
    }
    /**
    * The hasWon method.
    *
    * This method returns true if one of the
    * players has won the game.
    */
    public boolean hasWon() {
    boolean status = false;
    // check for a horizontal win
    for (int WIDTH=0; WIDTH<6; WIDTH++) {
    for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
    if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE)  &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH]) {
    status = true;
    }
    }
    }
    // check for a vertical win
    for (int WIDTH=0; WIDTH<3; WIDTH++) {
    for (int HEIGHT=0; HEIGHT<7; HEIGHT++) {
    if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE)  &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+1] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+2] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+3]) {
    status = true;
    }
    }
    }
    // check for a diagonal win (positive slope)
    for (int WIDTH=0; WIDTH<3; WIDTH++) {
    for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
        if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE) &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH+1] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH+2] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH+3]) {
    status = true;
    }
    }
    }
    // check for a diagonal win (negative slope)
    for (int WIDTH=3; WIDTH<6; WIDTH++) {
    for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
        if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE)  &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH-1] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH-2] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH-3]) {
    status = true;
    }
    }
    }
    return status;
    }

    private boolean isValidCell(int x, int y)
    {
        return x >= 0 && x < WIDTH
              && x>= 0 && x<HEIGHT
              && y >= 0 && y < WIDTH
              && y>= 0 && y<HEIGHT;
    }
}

package UI;

import java.awt.*;

import javax.swing.*;

import UI.ConnectFourBoardPanel;

import Game.ConnectFourBoard;
import Game.ConnectFourListener;

public class ConnectFourFrame extends JFrame implements ConnectFourListener {

    // Variables

    private ConnectFourBoard board;

    private JLabel scoreLabel;
    private ConnectFourBoardPanel boardPanel;
    private JLabel statusLabel;

    public ConnectFourFrame()
    {
        // The frame builds its own model.
        ConnectFourBoard board = new ConnectFourBoard();

        // We want the frame to receive notifications from the board as its
        // state changes.
        System.out.println(this);
        board.addConnectFourListener(this);

        setTitle("Informatics 45 Spring 2011: ConnectFour Game");
        setSize(700, 700);
        setResizable(true);
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        getContentPane().setBackground(Color.BLACK);

        buildUI();
        refreshUI();
    }

    private void buildUI()
    {
        GridBagLayout layout = new GridBagLayout();
        getContentPane().setLayout(layout);

        Font labelFont = new Font("SansSerif", Font.BOLD, 18);

        scoreLabel = new JLabel();
        scoreLabel.setForeground(Color.WHITE);
        scoreLabel.setFont(labelFont);
        layout.setConstraints(
            scoreLabel,
            new GridBagConstraints(
                0, 0, 1, 1, 1.0, 0.0,
                GridBagConstraints.CENTER,
                GridBagConstraints.NONE,
                new Insets(10, 10, 10, 10), 0, 0));
        getContentPane().add(scoreLabel);

        boardPanel = new ConnectFourBoardPanel(board);
        layout.setConstraints(
            boardPanel,
            new GridBagConstraints(
                0, 1, 1, 1, 1.0, 1.0,
                GridBagConstraints.CENTER,
                GridBagConstraints.BOTH,
                new Insets(10, 10, 10, 10), 0, 0));
        getContentPane().add(boardPanel);

        statusLabel = new JLabel();
        statusLabel.setForeground(Color.WHITE);
        statusLabel.setFont(labelFont);
        layout.setConstraints(
            statusLabel,
            new GridBagConstraints(
                0, 2, 1, 1, 1.0, 0.0,
                GridBagConstraints.CENTER,
                GridBagConstraints.NONE,
                new Insets(10, 10, 10, 10), 0, 0));
        getContentPane().add(statusLabel);
    }

    private void refreshUI()
    {
        // Refreshing the UI means to change the text in each of the
        // two labels (the score and the status) and also to ask the
        // board to repaint itself.

        scoreLabel.setText(
            "Blue: " + board.getBlueScore() +
            "          Red: " + board.getRedScore());

        statusLabel.setText(
            (board.isBlueTurn() ? "Blue's" : "Red's")
            + " turn");

        boardPanel.repaint();
    }

    // These are the ConnectFourBoardListener event-handling methods.

    public void boardChanged()
    {
        // When the board changes, we'll refresh the entire UI.  (There
        // are times when this approach is too inefficient, but it will
        // work fine for our relatively simple UI.)

        refreshUI();
    }

    public void gameOver()
    {
        // When the game is over, we'll pop up a message box showing the final
        // score, then, after the user dismisses the message box, dispose of
        // this window and end the program.

        JOptionPane.showMessageDialog(
            this,
            "Game over!\nFinal score: " + scoreLabel.getText(),
            "Game Over",
            JOptionPane.INFORMATION_MESSAGE);

        dispose();
    }

}
</code>```

答: It would be helpful to see a full stracktrace, however getBlueScore() and getRedScore() appear to be returning integers, which you're trying to set with setText() which will be expecting a string.

Body:
Im having a problem with my main method, whenevr I run it my code cant compile because of this problem :
"Exception in thread "main" java.lang.NullPointerException
    at UI.ConnectFourFrame.refreshUI(ConnectFourFrame.java:96)
    at UI.ConnectFourFrame.(ConnectFourFrame.java:43)
    at main.main(main.java:11)"

I am trying to see what the issue is but I cant figure it out, can someone help me

package Game;

import java.util.ArrayList;

public class ConnectFourBoard {

    // This constant is used to indicate the width and height, in cells,
    // of the board.  Since we want an 8x8 board, we'll set it to 8.
    private static final int WIDTH = 7;
    private static final int HEIGHT = 6;
    private ConnectFourCell[][] currentPlayer;

    // The current state the Othello board is defined with these two
    // fields: a two-dimensional array holding the state of each cell,
    // and a boolean value indicating whether it's the black player's
    // turn (true) or the white player's turn (false).
    private ConnectFourCell[][] cells;
    private boolean isBlueTurn;

    // Since the board is a model and it needs to notify views of changes,
    // it will employ the standard "listener" mechanism of tracking a list
    // of listeners and firing "events" (by calling methods on those
    // listeners) when things change.
    private ArrayList<ConnectFourListener> listeners;

    public ConnectFourBoard()
    {
        // Arrays, in Java, are objects, which means that variables of
        // array types (like cells, which has type OthelloCell[][]) are
        // really references that say where an array lives.  By default,
        // references point to null.  So we'll need to create an actual
        // two-dimensional array for "cells" to point to.
        cells = new ConnectFourCell[WIDTH][HEIGHT];
        listeners = new ArrayList<ConnectFourListener>();
        reset();
    }

    public void reset(){
        for (int i = 0; i<WIDTH ; i++){
            for (int j = 0; j<HEIGHT; j++){

                cells[i][j] = ConnectFourCell.NONE;
            }
        }

        isBlueTurn = true;
    }

    public void addConnectFourListener(ConnectFourListener listener)
    {
        listeners.add(listener);
    }

    public void removeConnectFourListener(ConnectFourListener listener)
    {
        if (listeners.contains(listener))
        {
            listeners.remove(listener);
        }
    }

    // These are fairly standard "fire event" methods that we've been building
    // all quarter, one corresponding to each method in the listener interface.

    private void fireBoardChanged()
    {
        for (ConnectFourListener listener : listeners)
        {
            listener.boardChanged();
        }
    }

    private void fireGameOver()
    {
        for (ConnectFourListener listener : listeners)
        {
            listener.gameOver();
        }
    }

    // isBlackTurn() returns true if it's the black player's turn, and false
    // if it's the white player's turn.
    public boolean isBlueTurn()
    {
        return isBlueTurn;
    }

    public int getWidth()
    {
        return WIDTH;

    }

    public int getHeight(){

        return HEIGHT;
    }
    // getBlackScore() calculates the score for the black player.
    public int getBlackScore()
    {
        return getScore(ConnectFourCell.BLUE);
    }

    // getWhiteScore() calculates the score for the white player.
    public int getWhiteScore()
    {
        return getScore(ConnectFourCell.RED);
    }

    // getScore() runs through all the cells on the board and counts the
    // number of cells that have a particular value (e.g., BLACK or WHITE).
    // This method uses the naive approach of counting them each time
    // it's called; it might be better to keep track of this score as we
    // go, updating it as tiles are added and flipped.
    private int getScore(ConnectFourCell cellValue)
    {
        int score = 0;

        for (int i = 0; i < WIDTH; i++)
        {
            for (int j = 0; j < HEIGHT; j++)
            {
                if (cells[i][j] == cellValue)
                {
                    score++;
                }
            }
        }

        return score;
    }

    // getWhiteScore() calculates the score for the white player.
    public int getRedScore()
    {
        return getScore(ConnectFourCell.RED);
    }

    public int getBlueScore() {
        // TODO Auto-generated method stub
        return getScore(ConnectFourCell.BLUE);
    }

    public ConnectFourCell getCell(int x, int y)
    {
        if (!isValidCell(x, y))
        {
            throw new IllegalArgumentException(
                "(" + x + ", " + y + ") is not a valid cell");
        }

        return cells[x][y];
    }
    /**
    * The drop method.
    *
    * Drop a checker into the specified HEIGHT,
    * and return the WIDTH that the checker lands on.
    */
    int drop(int HEIGHT) {
    if (hasWon()) {
    return -1;
    }

    for ( ; WIDTH<6 && HEIGHT != 0; WIDTH++) { };

    if (WIDTH==6) {
    // if the WIDTH is 6, it went through all 6 WIDTHs
    // of the cells, and couldn't find an empty one.
    // Therefore, return false to indicate that this
    // drop operation failed.
    return -1;
    }
    // fill the WIDTH of that HEIGHT with a checker.
    cells[HEIGHT][WIDTH] = currentPlayer[HEIGHT][WIDTH];
    // alternate the players
    //currentPlayer = (currentPlayer%2)+1;
    return WIDTH;
    }
    /**
    * The toString method
    *
    * Returns a String representation of this
    * Connect Four (TM) game.
    */
    public String toString() {
    String returnString = "";
    for (int WIDTH=5; WIDTH>=0; WIDTH--) {
    for (int HEIGHT=0; HEIGHT<7; HEIGHT++) {
    returnString = returnString + cells[HEIGHT][WIDTH];
    }
    returnString = returnString + "\n";
    }
    return returnString;
    }
    /**
    * The hasWon method.
    *
    * This method returns true if one of the
    * players has won the game.
    */
    public boolean hasWon() {
    boolean status = false;
    // check for a horizontal win
    for (int WIDTH=0; WIDTH<6; WIDTH++) {
    for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
    if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE)  &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH]) {
    status = true;
    }
    }
    }
    // check for a vertical win
    for (int WIDTH=0; WIDTH<3; WIDTH++) {
    for (int HEIGHT=0; HEIGHT<7; HEIGHT++) {
    if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE)  &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+1] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+2] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+3]) {
    status = true;
    }
    }
    }
    // check for a diagonal win (positive slope)
    for (int WIDTH=0; WIDTH<3; WIDTH++) {
    for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
        if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE) &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH+1] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH+2] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH+3]) {
    status = true;
    }
    }
    }
    // check for a diagonal win (negative slope)
    for (int WIDTH=3; WIDTH<6; WIDTH++) {
    for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
        if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE)  &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH-1] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH-2] &&
    cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH-3]) {
    status = true;
    }
    }
    }
    return status;
    }

    private boolean isValidCell(int x, int y)
    {
        return x >= 0 && x < WIDTH
              && x>= 0 && x<HEIGHT
              && y >= 0 && y < WIDTH
              && y>= 0 && y<HEIGHT;
    }
}

package UI;

import java.awt.*;

import javax.swing.*;

import UI.ConnectFourBoardPanel;

import Game.ConnectFourBoard;
import Game.ConnectFourListener;

public class ConnectFourFrame extends JFrame implements ConnectFourListener {

    // Variables

    private ConnectFourBoard board;

    private JLabel scoreLabel;
    private ConnectFourBoardPanel boardPanel;
    private JLabel statusLabel;

    public ConnectFourFrame()
    {
        // The frame builds its own model.
        ConnectFourBoard board = new ConnectFourBoard();

        // We want the frame to receive notifications from the board as its
        // state changes.
        System.out.println(this);
        board.addConnectFourListener(this);

        setTitle("Informatics 45 Spring 2011: ConnectFour Game");
        setSize(700, 700);
        setResizable(true);
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        getContentPane().setBackground(Color.BLACK);

        buildUI();
        refreshUI();
    }

    private void buildUI()
    {
        GridBagLayout layout = new GridBagLayout();
        getContentPane().setLayout(layout);

        Font labelFont = new Font("SansSerif", Font.BOLD, 18);

        scoreLabel = new JLabel();
        scoreLabel.setForeground(Color.WHITE);
        scoreLabel.setFont(labelFont);
        layout.setConstraints(
            scoreLabel,
            new GridBagConstraints(
                0, 0, 1, 1, 1.0, 0.0,
                GridBagConstraints.CENTER,
                GridBagConstraints.NONE,
                new Insets(10, 10, 10, 10), 0, 0));
        getContentPane().add(scoreLabel);

        boardPanel = new ConnectFourBoardPanel(board);
        layout.setConstraints(
            boardPanel,
            new GridBagConstraints(
                0, 1, 1, 1, 1.0, 1.0,
                GridBagConstraints.CENTER,
                GridBagConstraints.BOTH,
                new Insets(10, 10, 10, 10), 0, 0));
        getContentPane().add(boardPanel);

        statusLabel = new JLabel();
        statusLabel.setForeground(Color.WHITE);
        statusLabel.setFont(labelFont);
        layout.setConstraints(
            statusLabel,
            new GridBagConstraints(
                0, 2, 1, 1, 1.0, 0.0,
                GridBagConstraints.CENTER,
                GridBagConstraints.NONE,
                new Insets(10, 10, 10, 10), 0, 0));
        getContentPane().add(statusLabel);
    }

    private void refreshUI()
    {
        // Refreshing the UI means to change the text in each of the
        // two labels (the score and the status) and also to ask the
        // board to repaint itself.

        scoreLabel.setText(
            "Blue: " + board.getBlueScore() +
            "          Red: " + board.getRedScore());

        statusLabel.setText(
            (board.isBlueTurn() ? "Blue's" : "Red's")
            + " turn");

        boardPanel.repaint();
    }

    // These are the ConnectFourBoardListener event-handling methods.

    public void boardChanged()
    {
        // When the board changes, we'll refresh the entire UI.  (There
        // are times when this approach is too inefficient, but it will
        // work fine for our relatively simple UI.)

        refreshUI();
    }

    public void gameOver()
    {
        // When the game is over, we'll pop up a message box showing the final
        // score, then, after the user dismisses the message box, dispose of
        // this window and end the program.

        JOptionPane.showMessageDialog(
            this,
            "Game over!\nFinal score: " + scoreLabel.getText(),
            "Game Over",
            JOptionPane.INFORMATION_MESSAGE);

        dispose();
    }

}


问:
Prevent on click on parent A tag when clicking button inside
I have problems with product cards on index page.
Inside product card I have Vue component to render form (quantity and add to cart button).
When I click on add to cart button I get expected result. Response is sent to root vue component and then I see toast notification that product is added to cart.
But when I click on plus, minus buttons or input field then href link is triggered from parent A tag.

How to disable it?
I found this Prevent on click on parent when clicking button inside div

But it works only if I put A tag inside vue component. I don't want to put too much html into vue.

```<code>        @foreach ($products as $product)
        <a href="{{ $category->fullpath.'/'.$product->sef }}" class="catalog__card">
          <div class="catalog__card-img"><img src="/storage/img/products/{{ $product->mediumpic }}" alt="{{ $product->title }}"></div>

          <div class="card__properties">
            <div class="card__price"><span>{{ $product->price }}<span class="currencySymbol">₽</span></span></div>
            <div class="card__stock">
              @if ( $product->stock > 0 )
              <i class="far fa-check-circle text-success"></i><span class="text-success"><strong> on stock</strong></span>
              @else
                <span><strong> on request</strong></span>
              @endif
            </div>
            <addtocart @added_to_cart="updateCart"></addtocart>
          </div>
          <div class="catalog__card-title"><span>{{ $product->title }}</span></div>
        </a>
        @endforeach
</code>```

in Vue component I have following

```<code><template>

  <div class="cart">
    <form method="POST" id="add_to_cart" action="/add_to_cart" @submit.prevent="onSubmit">
      <input type="hidden" name="_token" :value="csrf">
      <div class="quantity">
        <button type="button" class="minus_quantity" v-on:click="minus_quantity" v-long-press="300" @long-press-start="longMinusStart" @long-press-stop="longMinusStop">-</button>
        <input type="number" class="input-text qty text" step="1" min="1" max="9999" name="quantity" value="1" title="Qty" v-model.number="quantity">
        <button type="button" class="plus_quantity" v-on:click="plus_quantity" v-long-press="300" @long-press-start="longPlusStart" @long-press-stop="longPlusStop">+</button>
      </div>
      <button type="submit" name="add-to-cart" class="button-cart"><i class="fas fa-cart-plus"></i><span> order</span></button>
    </form>
  </div>

</template>

<script>
    import LongPress from 'vue-directive-long-press';

    export default {

        name: "addtocart",

        data: function () {
          return {
            csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
            quantity: 1,
            plusInterval: null,
            minusInterval: null,
            success: false,
            errors: []
          }
        },

        directives: {
          'long-press': LongPress,
        },

        props: [],

        computed: {
          getName(){
             return this.$store.getters.Name
          }
        },

        methods: {
          // add to cart quantity plus and minus buttons
          // short mouse click event
          parent() { alert('you clicked the parent') },

          minus_quantity() {
            if (this.quantity > 0) {this.quantity -= 1}
          },
          plus_quantity() {this.quantity += 1},
          // long press buttons
          longPlusStart() {
            this.plusInterval = setInterval(() => {
              this.quantity += 1
            }, 100)
          },
          longPlusStop() {
            clearInterval(this.plusInterval)
          },
          longMinusStart() {
            this.minusInterval = setInterval(() => {
              if (this.quantity > 0) {this.quantity -= 1}
            }, 100)
          },
          longMinusStop() {
            clearInterval(this.minusInterval)
          },

          onSubmit() {
            axios.post('/add_to_cart', this.$data)
            .then(this.onSuccess)
            .catch(error => this.errors = error.response.data);
          },
          onSuccess(response) {
            this.success = true;
            this.$emit('added_to_cart', response);
          },

        },

        mounted() {

        },

    }
</script>
</code>```

答: using v-on:click.prevent instead v-on:click I fixed this issue

Body:
I have problems with product cards on index page.
Inside product card I have Vue component to render form (quantity and add to cart button).
When I click on add to cart button I get expected result. Response is sent to root vue component and then I see toast notification that product is added to cart.
But when I click on plus, minus buttons or input field then href link is triggered from parent A tag.

How to disable it?
I found this Prevent on click on parent when clicking button inside div

But it works only if I put A tag inside vue component. I don't want to put too much html into vue.

        @foreach ($products as $product)
        fullpath.'/'.$product->sef }}" class="catalog__card">

mediumpic }}" alt="{{ $product->title }}">

{{ $product->price }}₽

              @if ( $product->stock > 0 )
               on stock
              @else
                 on request
              @endif

            <addtocart @added_to_cart="updateCart"></addtocart>

{{ $product->title }}

        @endforeach

in Vue component I have following

<template>

    <form method="POST" id="add_to_cart" action="/add_to_cart" @submit.prevent="onSubmit">
      <input type="hidden" name="_token" :value="csrf">

        <button type="button" class="minus_quantity" v-on:click="minus_quantity" v-long-press="300" @long-press-start="longMinusStart" @long-press-stop="longMinusStop">-</button>
        <input type="number" class="input-text qty text" step="1" min="1" max="9999" name="quantity" value="1" title="Qty" v-model.number="quantity">
        <button type="button" class="plus_quantity" v-on:click="plus_quantity" v-long-press="300" @long-press-start="longPlusStart" @long-press-stop="longPlusStop">+</button>

      <button type="submit" name="add-to-cart" class="button-cart"> order</button>
    </form>

</template>


问:
error `require' /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require': cannot
I installed ubuntu and want to install Ruby on Rails. But tried few times and see same error after I run 'rails new app' I see error </p>

```<code>from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
/usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require': cannot load such file -- bundler/setup (LoadError)
</code>```

<p>The server also doesn't run because of it. </p>

答:
can you try below command?

echo $GEM_PATH

and check the ruby version, Is that different version then ruby/2.5.0?

and if it's different then set your $GEM_PATH from below command.

```<code>SetEnv GEM_HOME /usr/lib/ruby/gems/1.8(set your path)
</code>```

Body:
I installed ubuntu and want to install Ruby on Rails. But tried few times and see same error after I run 'rails new app' I see error

from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
/usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require': cannot load such file -- bundler/setup (LoadError)

The server also doesn't run because of it.

Body:
can you try below command?

echo $GEM_PATH

and check the ruby version, Is that different version then ruby/2.5.0?

and if it's different then set your $GEM_PATH from below command.

SetEnv GEM_HOME /usr/lib/ruby/gems/1.8(set your path)


问:
Tcl script to search strings and store in variable
```<code>Loop = (
      {
        Value = (
          {
           {
            Key :
            {
              A = "B";
              C = "D";
              Class = (
                {
                  section = "section_a";
                  Pairs = (
                    {
                      Name = "Ram";
                      Mark = "80";
                    },
                    {
                      Name = "Latha";
                      Mark = "70";
                    },
                    {
                      Name = "Mohan";
                      Mark = "90";
                    },
                    {
                      Name = "David";
                      Mark = "76";
                    } );
                } );
              Id = 1;
            };
            Absent :
            {
              DAYS = "Two days";
            };
          },
           {
            Key :
            {
              A = "B";
              C = "D";
              Class = (
                {
                  section = "section_b";
                  Pairs = (
                    {
                      Name = "Ram";
                      Mark = "30";
                    },
                    {
                      Name = "Latha";
                      Mark = "45";
                    },
                    {
                      Name = "Mohan";
                      Mark = "100";
                    },
                    {
                      Name = "David";
                      Mark = "76";
                    } );
                } );
              Id = 2;
            };
            Absent :
            {
              DAYS = "Four days";
            };
          },
          } );
      } );
</code>```

I am new to tcl script. I have a txt file in a above format. Using tcl script I have to store strings(section, Name , mark and Absent days) in a different variables to store in a csv file.
I tried below code to search the word Key

```<code>set search "Key"
set file [open "Marks.txt" r]
 while {[gets $file data] != -1} {
    if {[string match *[string toupper $search]* [string toupper $data]] } {
        puts "Found '$search' in the line '$data'"
    } else {
        puts "does not match"
    }
 }
</code>```

It is working to find the word key and printing whenever it matches. It works for that line which has the word Key. But, here I want to find the word Loop then I want search for the word Key in side loop. If it sees the word Key then it has to copy some strings present in the loop to variables. The word Key will be repeated in the files multiple times. After the word Key there will be {..} all over there file has some content. The script has to read the content and store it in some variable.

Exp: The script need to find the word Key in the text file, then look for the
section if present then section_b need to be stored in variable temp1(exp. temp1=section_a), Like wise:

If it sees Ram then Mark below the line needs to be stored in temp2 (exp. temp2=80).

If it sees Latha then Mark below the line needs to be stored in temp3 (exp. temp3=70).

then find id and need to to store the value 1 need to be stored in temp4(exp. temp4=1).

then Days meed to be stored in temp5(exp. temp5=Two days)

These temp values need to be written in the csv file everytime when it sees the word Key in the text file in below format.

```<code>section     Ram  Latha   id    Days
Section_a    80   70     1    Two days
Section_b    30   45     2    Four days
</code>```

Can you help me in writing the tcl script to get this. Thank you.

答:
This is the kind of thing that awk is really good for:

awk '
    function quoted(string,     a) {
        split(string, a, /"/)
        return a[2]
    }
    BEGIN { OFS="\t"; print "section", "Ram", "Latha", "id", "Days" }
    $1 == "section" {section = quoted($0); delete marks}
    $1 == "Name" {name = quoted($0)}
    $1 == "Mark" {marks[name] = quoted($0)}
    $1 == "Id" {id = gensub(/;/, "", 1, $3)}
    $1 == "DAYS" {print section, marks["Ram"], marks["Latha"], id, quoted($0)}
' file
```

<p>Translating that as a Tcl "one-liner", I'd write</p>

<pre class="lang-sh prettyprint-override"><code>echo '
    proc trim {str} {string trim $str {"}}
    puts "section\tRam\tLatha\tid\tdays"
    set fh [open [lindex $argv end]]
    while {[gets $fh line] != -1} {
        if {[regexp -- {(\S+) = ("[^"]+"|\d+);} $line -> key value]} {
            switch -exact -- $key {
                section {set section [trim $value]; array set marks {}}
                Name    {set name [trim $value]}
                Mark    {set marks($name) [trim $value]}
                Id      {set id $value}
                DAYS    {puts [join [list $section $marks(Ram) $marks(Latha) $id [trim $value]] \t]}
            }
        }
    }
' | tclsh - file
</code>```

Body:
Loop = (
      {
        Value = (
          {
           {
            Key :
            {
              A = "B";
              C = "D";
              Class = (
                {
                  section = "section_a";
                  Pairs = (
                    {
                      Name = "Ram";
                      Mark = "80";
                    },
                    {
                      Name = "Latha";
                      Mark = "70";
                    },
                    {
                      Name = "Mohan";
                      Mark = "90";
                    },
                    {
                      Name = "David";
                      Mark = "76";
                    } );
                } );
              Id = 1;
            };
            Absent :
            {
              DAYS = "Two days";
            };
          },
           {
            Key :
            {
              A = "B";
              C = "D";
              Class = (
                {
                  section = "section_b";
                  Pairs = (
                    {
                      Name = "Ram";
                      Mark = "30";
                    },
                    {
                      Name = "Latha";
                      Mark = "45";
                    },
                    {
                      Name = "Mohan";
                      Mark = "100";
                    },
                    {
                      Name = "David";
                      Mark = "76";
                    } );
                } );
              Id = 2;
            };
            Absent :
            {
              DAYS = "Four days";
            };
          },
          } );
      } );

I am new to tcl script. I have a txt file in a above format. Using tcl script I have to store strings(section, Name , mark and Absent days) in a different variables to store in a csv file.
I tried below code to search the word Key

set search "Key"
set file [open "Marks.txt" r]
 while {[gets $file data] != -1} {
    if {[string match *[string toupper $search]* [string toupper $data]] } {
        puts "Found '$search' in the line '$data'"
    } else {
        puts "does not match"
    }
 }

It is working to find the word key and printing whenever it matches. It works for that line which has the word Key. But, here I want to find the word Loop then I want search for the word Key in side loop. If it sees the word Key then it has to copy some strings present in the loop to variables. The word Key will be repeated in the files multiple times. After the word Key there will be {..} all over there file has some content. The script has to read the content and store it in some variable.

Exp: The script need to find the word Key in the text file, then look for the
section if present then section_b need to be stored in variable temp1(exp. temp1=section_a), Like wise:

If it sees Ram then Mark below the line needs to be stored in temp2 (exp. temp2=80).

If it sees Latha then Mark below the line needs to be stored in temp3 (exp. temp3=70).

then find id and need to to store the value 1 need to be stored in temp4(exp. temp4=1).

then Days meed to be stored in temp5(exp. temp5=Two days)

These temp values need to be written in the csv file everytime when it sees the word Key in the text file in below format.

section     Ram  Latha   id    Days
Section_a    80   70     1    Two days
Section_b    30   45     2    Four days

Can you help me in writing the tcl script to get this. Thank you.

Body:
This is the kind of thing that awk is really good for:

awk '
    function quoted(string,     a) {
        split(string, a, /"/)
        return a[2]
    }
    BEGIN { OFS="\t"; print "section", "Ram", "Latha", "id", "Days" }
    $1 == "section" {section = quoted($0); delete marks}
    $1 == "Name" {name = quoted($0)}
    $1 == "Mark" {marks[name] = quoted($0)}
    $1 == "Id" {id = gensub(/;/, "", 1, $3)}
    $1 == "DAYS" {print section, marks["Ram"], marks["Latha"], id, quoted($0)}
' file

Translating that as a Tcl "one-liner", I'd write

echo '
    proc trim {str} {string trim $str {"}}
    puts "section\tRam\tLatha\tid\tdays"
    set fh [open [lindex $argv end]]
    while {[gets $fh line] != -1} {
        if {[regexp -- {(\S+) = ("[^"]+"|\d+);} $line -> key value]} {
            switch -exact -- $key {
                section {set section [trim $value]; array set marks {}}
                Name    {set name [trim $value]}
                Mark    {set marks($name) [trim $value]}
                Id      {set id $value}
                DAYS    {puts [join [list $section $marks(Ram) $marks(Latha) $id [trim $value]] \t]}
            }
        }
    }
' | tclsh - file


问:
RISC-V assembly - stack layout - function call
Currently I am working with a RISC-V processor implementation. I need to run partially hand-crafted assembly code. (Finally there will be dynamic code injection.) For this purpose I have to understand the basics of function calls within RISC-V assembly.

I found this topic very helpful: confusion about function call stack

But I am still struggling with the stack layout for a function call. Please consider the following c-code:

```<code>void some_func(int a, int b, int* c){
   int cnt = a;
   for(;cnt > 0;cnt--){
      *c += b;
   }
}

void main(){
   int a = 5;
   int b = 6;
   int c = 0;

   some_func(a,b,&c);
}
</code>```

This program implements a basic multiplication by a sequence of additions. The derived assembly code (riscv64-unknown-elf-gcc -nostartfiles mul.c -o mul && riscv64-unknown-elf-objdump -D mul) looks like this:

```<code>0000000000010000 <some_func>:
   10000:   fd010113            addi    sp,sp,-48
   10004:   02813423            sd  s0,40(sp)
   10008:   03010413            addi    s0,sp,48
   1000c:   fca42e23            sw  a0,-36(s0)
   10010:   fcb42c23            sw  a1,-40(s0)
   10014:   fcc43823            sd  a2,-48(s0)
   10018:   fdc42783            lw  a5,-36(s0)
   1001c:   fef42623            sw  a5,-20(s0)
   10020:   0280006f            j   10048 <some_func+0x48>
   10024:   fd043783            ld  a5,-48(s0)
   10028:   0007a703            lw  a4,0(a5)
   1002c:   fd842783            lw  a5,-40(s0)
   10030:   00f7073b            addw    a4,a4,a5
   10034:   fd043783            ld  a5,-48(s0)
   10038:   00e7a023            sw  a4,0(a5)
   1003c:   fec42783            lw  a5,-20(s0)
   10040:   fff7879b            addiw   a5,a5,-1
   10044:   fef42623            sw  a5,-20(s0)
   10048:   fec42783            lw  a5,-20(s0)
   1004c:   fcf04ce3            bgtz    a5,10024 <some_func+0x24>
   10050:   00000013            nop
   10054:   02813403            ld  s0,40(sp)
   10058:   03010113            addi    sp,sp,48
   1005c:   00008067            ret

0000000000010060 <main>:
   10060:   fe010113            addi    sp,sp,-32
   10064:   00113c23            sd  ra,24(sp)
   10068:   00813823            sd  s0,16(sp)
   1006c:   02010413            addi    s0,sp,32
   10070:   00500793            li  a5,5
   10074:   fef42623            sw  a5,-20(s0)
   10078:   00600793            li  a5,6
   1007c:   fef42423            sw  a5,-24(s0)
   10080:   fe042223            sw  zero,-28(s0)
   10084:   fe440793            addi    a5,s0,-28
   10088:   00078613            mv  a2,a5
   1008c:   fe842583            lw  a1,-24(s0)
   10090:   fec42503            lw  a0,-20(s0)
   10094:   f6dff0ef            jal 10000 <some_func>
   10098:   00000013            nop
   1009c:   01813083            ld  ra,24(sp)
   100a0:   01013403            ld  s0,16(sp)
   100a4:   02010113            addi    sp,sp,32
   100a8:   00008067            ret
</code>```

The important steps that need clarification are: (some_func(int,int,int))

```<code>   10060:   fe010113            addi    sp,sp,-32
   10064:   00113c23            sd  ra,24(sp)
   10068:   00813823            sd  s0,16(sp)
   1006c:   02010413            addi    s0,sp,32
</code>```

and: (main())

```<code>   10000:   fd010113            addi    sp,sp,-48
   10004:   02813423            sd  s0,40(sp)
   10008:   03010413            addi    s0,sp,48
</code>```

From my understanding: The stack pointer is moved to make space for return-address and parameters. (main might be a special case here.) How are the passed arguments treated when located on the stack? How are they obtained back? In general, the methodology is clear to me, but how would I hand-code this segment in order to work.

Regarding the related topic, the stack should look somewhat like

```<code>| ???                            |
| params for some_func() <???>   |
| ra of some_func()              |
| locals of main()       <int c> |
| locals of main()       <int b> |
| locals of main()       <int a> |
| params for main()      <None>  |
</code>```

But that is pretty much it. Can anybody point out, how this is arranged, and how these two listings (function call) co-related?

答:
What you want to know is specified by the RISC-V calling conventions.

Main points:

Function arguments are usually passed in the a0 to a7 registers, not on the stack. An argument is only passed via the stack if there is no room in the a* registers left.

Some registers are caller saved while others are callee saved (cf. Table 26.1, Chapter 26 RISC-V Assembly Programmer’s Handbook, in the RISC-V base specification, 2019-06-08 ratified). That means before calling a function the caller has to save all caller saved registers to the stack if it wants to retain their content. Similarly, the called function has to save all callee saved registers to the stack if it wants to use them for its own purposes.

Body:
Currently I am working with a RISC-V processor implementation. I need to run partially hand-crafted assembly code. (Finally there will be dynamic code injection.) For this purpose I have to understand the basics of function calls within RISC-V assembly.

I found this topic very helpful: confusion about function call stack

But I am still struggling with the stack layout for a function call. Please consider the following c-code:

void some_func(int a, int b, int* c){
   int cnt = a;
   for(;cnt > 0;cnt--){
      *c += b;
   }
}

void main(){
   int a = 5;
   int b = 6;
   int c = 0;

   some_func(a,b,&c);
}

This program implements a basic multiplication by a sequence of additions. The derived assembly code (riscv64-unknown-elf-gcc -nostartfiles mul.c -o mul && riscv64-unknown-elf-objdump -D mul) looks like this:

0000000000010000 <some_func>:
   10000:   fd010113            addi    sp,sp,-48
   10004:   02813423            sd  s0,40(sp)
   10008:   03010413            addi    s0,sp,48
   1000c:   fca42e23            sw  a0,-36(s0)
   10010:   fcb42c23            sw  a1,-40(s0)
   10014:   fcc43823            sd  a2,-48(s0)
   10018:   fdc42783            lw  a5,-36(s0)
   1001c:   fef42623            sw  a5,-20(s0)
   10020:   0280006f            j   10048 <some_func+0x48>
   10024:   fd043783            ld  a5,-48(s0)
   10028:   0007a703            lw  a4,0(a5)
   1002c:   fd842783            lw  a5,-40(s0)
   10030:   00f7073b            addw    a4,a4,a5
   10034:   fd043783            ld  a5,-48(s0)
   10038:   00e7a023            sw  a4,0(a5)
   1003c:   fec42783            lw  a5,-20(s0)
   10040:   fff7879b            addiw   a5,a5,-1
   10044:   fef42623            sw  a5,-20(s0)
   10048:   fec42783            lw  a5,-20(s0)
   1004c:   fcf04ce3            bgtz    a5,10024 <some_func+0x24>
   10050:   00000013            nop
   10054:   02813403            ld  s0,40(sp)
   10058:   03010113            addi    sp,sp,48
   1005c:   00008067            ret

0000000000010060 :
   10060:   fe010113            addi    sp,sp,-32
   10064:   00113c23            sd  ra,24(sp)
   10068:   00813823            sd  s0,16(sp)
   1006c:   02010413            addi    s0,sp,32
   10070:   00500793            li  a5,5
   10074:   fef42623            sw  a5,-20(s0)
   10078:   00600793            li  a5,6
   1007c:   fef42423            sw  a5,-24(s0)
   10080:   fe042223            sw  zero,-28(s0)
   10084:   fe440793            addi    a5,s0,-28
   10088:   00078613            mv  a2,a5
   1008c:   fe842583            lw  a1,-24(s0)
   10090:   fec42503            lw  a0,-20(s0)
   10094:   f6dff0ef            jal 10000 <some_func>
   10098:   00000013            nop
   1009c:   01813083            ld  ra,24(sp)
   100a0:   01013403            ld  s0,16(sp)
   100a4:   02010113            addi    sp,sp,32
   100a8:   00008067            ret

The important steps that need clarification are: (some_func(int,int,int))

   10060:   fe010113            addi    sp,sp,-32
   10064:   00113c23            sd  ra,24(sp)
   10068:   00813823            sd  s0,16(sp)
   1006c:   02010413            addi    s0,sp,32

and: (main())

   10000:   fd010113            addi    sp,sp,-48
   10004:   02813423            sd  s0,40(sp)
   10008:   03010413            addi    s0,sp,48

From my understanding: The stack pointer is moved to make space for return-address and parameters. (main might be a special case here.) How are the passed arguments treated when located on the stack? How are they obtained back? In general, the methodology is clear to me, but how would I hand-code this segment in order to work.

Regarding the related topic, the stack should look somewhat like

| ???                            |
| params for some_func() <???>   |
| ra of some_func()              |
| locals of main()       <int c> |
| locals of main()       <int b> |
| locals of main()       <int a> |
| params for main()      <None>  |

But that is pretty much it. Can anybody point out, how this is arranged, and how these two listings (function call) co-related?


问:
React MUI datatable date range filter
I am new in mui datatables and I was wondering is there a way to create date range filter(from date - to date) using mui-datatables ?

Any suggestions will be appreciated.

答:
You can use the filterOptions value on a column to customize how the filter component renders, what values are available based on the current state, and can provide a strategy on how the actual filter impacts the table dataset.

Check out the customize-filter example on github to see how this works: https://github.com/gregnb/mui-datatables/blob/master/examples/customize-filter/index.js

Specifically, here is a column configuration that defines options.filterOptions.logic as a numeric (ie convert date boundaries to epoch):

```<code>  {
    name: 'Age',
    options: {
      filter: true,
      filterType: 'custom',
      filterList: [25, 50],
      customFilterListOptions: {
        render: v => {
          if (v[0] && v[1] && this.state.ageFilterChecked) {
            return [`Min Age: ${v[0]}`, `Max Age: ${v[1]}`];
          } else if (v[0] && v[1] && !this.state.ageFilterChecked) {
            return `Min Age: ${v[0]}, Max Age: ${v[1]}`;
          } else if (v[0]) {
            return `Min Age: ${v[0]}`;
          } else if (v[1]) {
            return `Max Age: ${v[1]}`;
          }
          return false;
        },
        update: (filterList, filterPos, index) => {
          console.log('customFilterListOnDelete: ', filterList, filterPos, index);

          if (filterPos === 0) {
            filterList[index].splice(filterPos, 1, '');
          } else if (filterPos === 1) {
            filterList[index].splice(filterPos, 1);
          } else if (filterPos === -1) {
            filterList[index] = [];
          }

          return filterList;
        },
      },
      filterOptions: {
        names: [],
        logic(age, filters) {
          if (filters[0] && filters[1]) {
            return age < filters[0] || age > filters[1];
          } else if (filters[0]) {
            return age < filters[0];
          } else if (filters[1]) {
            return age > filters[1];
          }
          return false;
        },
        display: (filterList, onChange, index, column) => (
          <div>
            <FormLabel>Age</FormLabel>
            <FormGroup row>
              <TextField
                label='min'
                value={filterList[index][0] || ''}
                onChange={event => {
                  filterList[index][0] = event.target.value;
                  onChange(filterList[index], index, column);
                }}
                style={{ width: '45%', marginRight: '5%' }}
              />
              <TextField
                label='max'
                value={filterList[index][1] || ''}
                onChange={event => {
                  filterList[index][1] = event.target.value;
                  onChange(filterList[index], index, column);
                }}
                style={{ width: '45%' }}
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={this.state.ageFilterChecked}
                    onChange={event => this.setState({ ageFilterChecked: event.target.checked })}
                  />
                }
                label='Separate Values'
                style={{ marginLeft: '0px' }}
              />
            </FormGroup>
          </div>
        ),
      },
      print: false,
    },
  },
</code>```

Title: React MUI datatable date range filter

Body:
You can use the filterOptions value on a column to customize how the filter component renders, what values are available based on the current state, and can provide a strategy on how the actual filter impacts the table dataset.

Check out the customize-filter example on github to see how this works: https://github.com/gregnb/mui-datatables/blob/master/examples/customize-filter/index.js

Specifically, here is a column configuration that defines options.filterOptions.logic as a numeric (ie convert date boundaries to epoch):

  {
    name: 'Age',
    options: {
      filter: true,
      filterType: 'custom',
      filterList: [25, 50],
      customFilterListOptions: {
        render: v => {
          if (v[0] && v[1] && this.state.ageFilterChecked) {
            return [`Min Age: ${v[0]}`, `Max Age: ${v[1]}`];
          } else if (v[0] && v[1] && !this.state.ageFilterChecked) {
            return `Min Age: ${v[0]}, Max Age: ${v[1]}`;
          } else if (v[0]) {
            return `Min Age: ${v[0]}`;
          } else if (v[1]) {
            return `Max Age: ${v[1]}`;
          }
          return false;
        },
        update: (filterList, filterPos, index) => {
          console.log('customFilterListOnDelete: ', filterList, filterPos, index);

          if (filterPos === 0) {
            filterList[index].splice(filterPos, 1, '');
          } else if (filterPos === 1) {
            filterList[index].splice(filterPos, 1);
          } else if (filterPos === -1) {
            filterList[index] = [];
          }

          return filterList;
        },
      },
      filterOptions: {
        names: [],
        logic(age, filters) {
          if (filters[0] && filters[1]) {
            return age < filters[0] || age > filters[1];
          } else if (filters[0]) {
            return age < filters[0];
          } else if (filters[1]) {
            return age > filters[1];
          }
          return false;
        },
        display: (filterList, onChange, index, column) => (
          <div>
            <FormLabel>Age</FormLabel>
            <FormGroup row>
              <TextField
                label='min'
                value={filterList[index][0] || ''}
                onChange={event => {
                  filterList[index][0] = event.target.value;
                  onChange(filterList[index], index, column);
                }}
                style={{ width: '45%', marginRight: '5%' }}
              />
              <TextField
                label='max'
                value={filterList[index][1] || ''}
                onChange={event => {
                  filterList[index][1] = event.target.value;
                  onChange(filterList[index], index, column);
                }}
                style={{ width: '45%' }}
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={this.state.ageFilterChecked}
                    onChange={event => this.setState({ ageFilterChecked: event.target.checked })}
                  />
                }
                label='Separate Values'
                style={{ marginLeft: '0px' }}
              />
            </FormGroup>
          </div>
        ),
      },
      print: false,
    },
  },


问:
How to avoid unexpected rendering while using React Context?
I have two functional component under my provider,

SubApp1 and SubApp2 and here when I am increasing counter1 in SubApp1 the SubApp2 also is rendering, even when it is not need to be re-rendered.

And when I am increasing counter2 in SubApp2 the SubApp1 also is rendering.

I know this happens regally, but How can avoid this situation ?

App.js:

```<code>import React, {useContext, useState, memo} from "react";
import "./styles.css";

export const MainContext = React.createContext();

export const MainProvider = ({children})=> {

  const [counter1, setCounter1] = useState(0);
  const [counter2, setCounter2] = useState(0);

  return (
    <MainContext.Provider value={{
      counter1, setCounter1,
      counter2, setCounter2,
    }}>
      {children}
    </MainContext.Provider>
  );
}

export const SubApp1 = memo(()=> {
  const {counter1, setCounter1} = useContext(MainContext);
  console.log('Counter 1: ', counter1);
  return (
    <div className="App">
          <button onClick={()=> {
            setCounter1(counter1+1);
          }}>
            Increase Count 1
          </button>
    </div>
  );
});

export const SubApp2 = memo(()=> {

  const {counter2, setCounter2} = useContext(MainContext);

  console.log('counter2: ', counter2);

  return (
    <div className="App">
          <button onClick={()=> {
            setCounter2(counter2+1);
          }}>
            Increase Count 2
          </button>
    </div>
  );
});

export default function App ({navigation}){

  console.log('App Is rendering...');

  return (
    <div className="App">

         <button onClick={()=> {
            navigation.navigate('SubApp1');
          }}>
            navigate to SubApp1
          </button>

          <button onClick={()=> {
            navigation.navigate('SubApp2');
          }}>
            navigate to SubApp2
          </button>

    </div>
  );
}
</code>```

index.js:

```<code>import React from "react";
import ReactDOM from "react-dom";

import App, {MainProvider} from "./App";

const MainApp = ()=> (
  <MainProvider>
    <App />
  </MainProvider>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<MainApp />, rootElement);
</code>```

答:
You should pass the counter to the SubApps as props. Then memo will take care that only the component with changing props will be rerendered.

Something like this:

```<code>export const Wrapper1 = ()=> {
  const {counter1, setCounter1} = useContext(MainContext);
  return (
    <SubApp1 {...{counter1, setCounter1}} />
  );
};

export const SubApp1 = memo(({counter1, setCounter1})=> {

  console.log('Counter 1: ', counter1);
  return (
    <div className="App">
          <button onClick={()=> {
            setCounter1(counter1+1);
          }}>
            Increase Count 1
          </button>
    </div>
  );
});

export const SubApp2 = memo(({counter2, setCounter2})=> {
  console.log('counter2: ', counter2);

  return (
    <div className="App">
          <button onClick={()=> {
            setCounter2(counter2+1);
          }}>
            Increase Count 2
          </button>
    </div>
  );
});

export default function App (){

  const {counter2, setCounter2} = useContext(MainContext);

  console.log('App Is rendering...');

  return (
    <div className="App">
        <Wrapper1/>
        <SubApp2 {...{counter2, setCounter2}} />
    </div>
  );
}
</code>```

Codesandbox link is not right...

Body:
I have two functional component under my provider,

SubApp1 and SubApp2 and here when I am increasing counter1 in SubApp1 the SubApp2 also is rendering, even when it is not need to be re-rendered.

And when I am increasing counter2 in SubApp2 the SubApp1 also is rendering.

I know this happens regally, but How can avoid this situation ?

App.js:

import React, {useContext, useState, memo} from "react";
import "./styles.css";

export const MainContext = React.createContext();

export const MainProvider = ({children})=> {

  const [counter1, setCounter1] = useState(0);
  const [counter2, setCounter2] = useState(0);

  return (
    <MainContext.Provider value={{
      counter1, setCounter1,
      counter2, setCounter2,
    }}>
      {children}
    </MainContext.Provider>
  );
}

export const SubApp1 = memo(()=> {
  const {counter1, setCounter1} = useContext(MainContext);
  console.log('Counter 1: ', counter1);
  return (

          <button onClick={()=> {
            setCounter1(counter1+1);
          }}>
            Increase Count 1
          </button>

  );
});

export const SubApp2 = memo(()=> {

  const {counter2, setCounter2} = useContext(MainContext);

  console.log('counter2: ', counter2);

  return (

          <button onClick={()=> {
            setCounter2(counter2+1);
          }}>
            Increase Count 2
          </button>

  );
});

export default function App ({navigation}){

  console.log('App Is rendering...');

  return (

         <button onClick={()=> {
            navigation.navigate('SubApp1');
          }}>
            navigate to SubApp1
          </button>

          <button onClick={()=> {
            navigation.navigate('SubApp2');
          }}>
            navigate to SubApp2
          </button>

  );
}

index.js:

import React from "react";
import ReactDOM from "react-dom";

import App, {MainProvider} from "./App";

const MainApp = ()=> (
  <MainProvider>
    <App />
  </MainProvider>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<MainApp />, rootElement);

Body:
You should pass the counter to the SubApps as props. Then memo will take care that only the component with changing props will be rerendered.

Something like this:

export const Wrapper1 = ()=> {
  const {counter1, setCounter1} = useContext(MainContext);
  return (
    <SubApp1 {...{counter1, setCounter1}} />
  );
};

export const SubApp1 = memo(({counter1, setCounter1})=> {

  console.log('Counter 1: ', counter1);
  return (
    <div className="App">
          <button onClick={()=> {
            setCounter1(counter1+1);
          }}>
            Increase Count 1
          </button>
    </div>
  );
});

export const SubApp2 = memo(({counter2, setCounter2})=> {
  console.log('counter2: ', counter2);

  return (
    <div className="App">
          <button onClick={()=> {
            setCounter2(counter2+1);
          }}>
            Increase Count 2
          </button>
    </div>
  );
});

export default function App (){

  const {counter2, setCounter2} = useContext(MainContext);

  console.log('App Is rendering...');

  return (
    <div className="App">
        <Wrapper1/>
        <SubApp2 {...{counter2, setCounter2}} />
    </div>
  );
}

Codesandbox link is not right...


问:
Best way to save huge text in android
So I was in need of a container to save a lot of dialogue for my apps(branching dialogue), I was thinking about using string value XML but I'm still not quite sure since I have a lot of text and need some kind of tag/attribute to do the branching,
can I have another value XML that only contain the dialogue text? or should I use SQLite database?
or are there any method best used for my case that I could learn?

Newbie here would appreciate any suggestions. Thanks in advance

答:
Xml parsing is a slow process plus adding overhead to write is to file storage and read it as it grows big will hurt your app performance, do consider doing multithreading for avoiding ANR and also Roomdb is best choice to store persistent database, learn more from

Guide to Room db

Title: Best way to save huge text in android